Update clunky auto to manual sorting by time, primary color blue
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user