Update clunky auto to manual sorting by time, primary color blue

This commit is contained in:
2025-12-03 23:58:19 +00:00
parent 63d6124ce3
commit bb5569aada
5 changed files with 80 additions and 14 deletions

View File

@@ -36,7 +36,8 @@ const MedPlanAssistant = () => {
removeDay, removeDay,
addDoseToDay, addDoseToDay,
removeDoseFromDay, removeDoseFromDay,
updateDoseInDay updateDoseInDay,
sortDosesInDay
} = useAppState(); } = useAppState();
const { const {
@@ -126,6 +127,7 @@ const MedPlanAssistant = () => {
onAddDose={addDoseToDay} onAddDose={addDoseToDay}
onRemoveDose={removeDoseFromDay} onRemoveDose={removeDoseFromDay}
onUpdateDose={updateDoseInDay} onUpdateDose={updateDoseInDay}
onSortDoses={sortDosesInDay}
t={t} t={t}
/> />
</div> </div>

View File

@@ -14,7 +14,8 @@ import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
import { Badge } from './ui/badge'; import { Badge } from './ui/badge';
import { FormTimeInput } from './ui/form-time-input'; import { FormTimeInput } from './ui/form-time-input';
import { FormNumericInput } from './ui/form-numeric-input'; import { FormNumericInput } from './ui/form-numeric-input';
import { Plus, Copy, Trash2 } from 'lucide-react'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip';
import { Plus, Copy, Trash2, ArrowDownAZ } from 'lucide-react';
import type { DayGroup } from '../constants/defaults'; import type { DayGroup } from '../constants/defaults';
interface DayScheduleProps { interface DayScheduleProps {
@@ -25,6 +26,7 @@ interface DayScheduleProps {
onAddDose: (dayId: string) => void; onAddDose: (dayId: string) => void;
onRemoveDose: (dayId: string, doseId: string) => void; onRemoveDose: (dayId: string, doseId: string) => void;
onUpdateDose: (dayId: string, doseId: string, field: 'time' | 'ldx' | 'damph', value: string) => void; onUpdateDose: (dayId: string, doseId: string, field: 'time' | 'ldx' | 'damph', value: string) => void;
onSortDoses: (dayId: string) => void;
t: any; t: any;
} }
@@ -36,10 +38,23 @@ const DaySchedule: React.FC<DayScheduleProps> = ({
onAddDose, onAddDose,
onRemoveDose, onRemoveDose,
onUpdateDose, onUpdateDose,
onSortDoses,
t t
}) => { }) => {
const canAddDay = days.length < 3; const canAddDay = days.length < 3;
// Check if doses are sorted chronologically
const isDaySorted = (day: DayGroup): boolean => {
for (let i = 1; i < day.doses.length; i++) {
const prevTime = day.doses[i - 1].time || '00:00';
const currTime = day.doses[i].time || '00:00';
if (prevTime > currTime) {
return false;
}
}
return true;
};
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{days.map((day, dayIndex) => ( {days.map((day, dayIndex) => (
@@ -82,7 +97,34 @@ const DaySchedule: React.FC<DayScheduleProps> = ({
<CardContent className="space-y-3"> <CardContent className="space-y-3">
{/* Dose table header */} {/* Dose table header */}
<div className="grid grid-cols-[120px_1fr_auto] gap-3 text-sm font-medium text-muted-foreground"> <div className="grid grid-cols-[120px_1fr_auto] gap-3 text-sm font-medium text-muted-foreground">
<div>{t('time')}</div> <div className="flex items-center gap-2">
<span>{t('time')}</span>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
size="sm"
variant="ghost"
className={
isDaySorted(day)
? "h-6 w-6 p-0 text-muted-foreground hover:text-muted-foreground cursor-default"
: "h-6 w-6 p-0 text-primary hover:text-primary hover:bg-primary/10"
}
onClick={() => !isDaySorted(day) && onSortDoses(day.id)}
disabled={isDaySorted(day)}
>
<ArrowDownAZ className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p className="text-xs">
{isDaySorted(day) ? t('sortByTimeSorted') : t('sortByTimeNeeded')}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<div>{t('ldx')} (mg)</div> <div>{t('ldx')} (mg)</div>
<div></div> <div></div>
</div> </div>

View File

@@ -186,20 +186,11 @@ export const useAppState = () => {
days: prev.days.map(day => { days: prev.days.map(day => {
if (day.id !== dayId) return day; if (day.id !== dayId) return day;
// Update the dose field // Update the dose field (no auto-sort)
const updatedDoses = day.doses.map(dose => const updatedDoses = day.doses.map(dose =>
dose.id === doseId ? { ...dose, [field]: value } : dose dose.id === doseId ? { ...dose, [field]: value } : dose
); );
// Sort by time if time field was changed
if (field === 'time') {
updatedDoses.sort((a, b) => {
const timeA = a.time || '00:00';
const timeB = b.time || '00:00';
return timeA.localeCompare(timeB);
});
}
return { return {
...day, ...day,
doses: updatedDoses doses: updatedDoses
@@ -208,6 +199,26 @@ export const useAppState = () => {
})); }));
}; };
const sortDosesInDay = (dayId: string) => {
setAppState(prev => ({
...prev,
days: prev.days.map(day => {
if (day.id !== dayId) return day;
const sortedDoses = [...day.doses].sort((a, b) => {
const timeA = a.time || '00:00';
const timeB = b.time || '00:00';
return timeA.localeCompare(timeB);
});
return {
...day,
doses: sortedDoses
};
})
}));
};
const handleReset = () => { const handleReset = () => {
if (window.confirm("Bist du sicher, dass du alle Einstellungen auf die Standardwerte zurücksetzen möchtest? Dies kann nicht rückgängig gemacht werden.")) { if (window.confirm("Bist du sicher, dass du alle Einstellungen auf die Standardwerte zurücksetzen möchtest? Dies kann nicht rückgängig gemacht werden.")) {
window.localStorage.removeItem(LOCAL_STORAGE_KEY); window.localStorage.removeItem(LOCAL_STORAGE_KEY);
@@ -227,6 +238,7 @@ export const useAppState = () => {
addDoseToDay, addDoseToDay,
removeDoseFromDay, removeDoseFromDay,
updateDoseInDay, updateDoseInDay,
sortDosesInDay,
handleReset handleReset
}; };
}; };

View File

@@ -118,7 +118,12 @@ export const de = {
// Time picker // Time picker
timePickerHour: "Stunde", timePickerHour: "Stunde",
timePickerMinute: "Minute", timePickerMinute: "Minute",
timePickerApply: "Übernehmen" timePickerApply: "Übernehmen",
// Sorting
sortByTime: "Nach Zeit sortieren",
sortByTimeNeeded: "Dosen sind nicht in chronologischer Reihenfolge. Klicken zum Sortieren.",
sortByTimeSorted: "Dosen sind chronologisch sortiert."
}; };
export default de; export default de;

View File

@@ -99,6 +99,11 @@ export const en = {
timePickerMinute: "Minute", timePickerMinute: "Minute",
timePickerApply: "Apply", timePickerApply: "Apply",
// Sorting
sortByTime: "Sort by time",
sortByTimeNeeded: "Doses are not in chronological order. Click to sort.",
sortByTimeSorted: "Doses are sorted chronologically.",
// Day-based schedule // Day-based schedule
regularPlan: "Regular Plan", regularPlan: "Regular Plan",
deviatingPlan: "Deviation from Plan", deviatingPlan: "Deviation from Plan",