Formular und Liste responsiv gestalten
Eingabemaske als CSS-Grid statt starrer Tabelle, damit sie auf dem Smartphone vollständig sichtbar bleibt (2/4/8 Spalten je nach Breite). Einträge-Liste zeigt unterhalb von 768px eine zweizeilige Kartenansicht statt der breiten Tabelle. Anzahl geladener Einträge von 15 auf 5 reduziert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+117
-109
@@ -142,122 +142,130 @@ export default function WerteForm({ onSuccess, selectedEntry }: WerteFormProps)
|
||||
updateWeekday(now);
|
||||
};
|
||||
|
||||
const inputClass = "w-full min-w-0 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none";
|
||||
const numberInputClass = `${inputClass} [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none`;
|
||||
|
||||
return (
|
||||
<div className="bg-[#CCCCFF] border border-black p-6 rounded-lg mb-6">
|
||||
<div className="bg-[#CCCCFF] border border-black p-3 sm: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 "Aktualisieren", um die Änderungen zu speichern, oder "Abbrechen", 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"
|
||||
min={0}
|
||||
max={999}
|
||||
value={formData.Zucker}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Zucker: e.target.value }))}
|
||||
/>
|
||||
</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"
|
||||
min={0}
|
||||
max={300}
|
||||
value={formData.Gewicht}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Gewicht: e.target.value }))}
|
||||
/>
|
||||
</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"
|
||||
min={0}
|
||||
max={300}
|
||||
value={formData.DruckS}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, DruckS: e.target.value }))}
|
||||
/>
|
||||
</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"
|
||||
min={0}
|
||||
max={200}
|
||||
value={formData.DruckD}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, DruckD: e.target.value }))}
|
||||
/>
|
||||
</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"
|
||||
min={0}
|
||||
max={250}
|
||||
value={formData.Puls}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Puls: e.target.value }))}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="flex justify-center gap-4 mt-6">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-8 gap-3 sm:gap-2">
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Datum
|
||||
<span className="block text-[10px] font-normal">{weekday}</span>
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
className={inputClass}
|
||||
value={formData.Datum}
|
||||
onChange={(e) => handleDateChange(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Zeit
|
||||
<span className="block text-[10px] font-normal invisible">.</span>
|
||||
</label>
|
||||
<input
|
||||
type="time"
|
||||
className={inputClass}
|
||||
value={formData.Zeit}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Zeit: e.target.value }))}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Zucker
|
||||
<span className="block text-[10px] font-normal">mg/dl</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
className={numberInputClass}
|
||||
min={0}
|
||||
max={999}
|
||||
value={formData.Zucker}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Zucker: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Essen
|
||||
<span className="block text-[10px] font-normal invisible">.</span>
|
||||
</label>
|
||||
<textarea
|
||||
className={`${inputClass} resize-none align-middle`}
|
||||
value={formData.Essen}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Essen: e.target.value }))}
|
||||
rows={1}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Gewicht
|
||||
<span className="block text-[10px] font-normal">kg</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
step="0.1"
|
||||
className={numberInputClass}
|
||||
min={0}
|
||||
max={300}
|
||||
value={formData.Gewicht}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Gewicht: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Druck sys
|
||||
<span className="block text-[10px] font-normal">mmHg</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
className={numberInputClass}
|
||||
min={0}
|
||||
max={300}
|
||||
value={formData.DruckS}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, DruckS: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Druck dia
|
||||
<span className="block text-[10px] font-normal">mmHg</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
className={numberInputClass}
|
||||
min={0}
|
||||
max={200}
|
||||
value={formData.DruckD}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, DruckD: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-medium text-center">
|
||||
Puls
|
||||
<span className="block text-[10px] font-normal">bpm</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
className={numberInputClass}
|
||||
min={0}
|
||||
max={250}
|
||||
value={formData.Puls}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, Puls: e.target.value }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-2 sm:gap-4 mt-6">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
|
||||
Reference in New Issue
Block a user