für Docker angepasst

This commit is contained in:
rxf
2026-02-22 22:11:52 +01:00
parent e14af11e5c
commit e28cca1c46
21 changed files with 1494 additions and 94 deletions

274
components/WerteForm.tsx Normal file
View File

@@ -0,0 +1,274 @@
'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"
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"
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"
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"
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"
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>
);
}