fixes
This commit is contained in:
@@ -112,6 +112,14 @@ function timeToMinutes(t: string): number {
|
|||||||
return h * 60 + m;
|
return h * 60 + m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function timeToMinutesLocal(t: string, offsetMinutes: number): number {
|
||||||
|
const mins = timeToMinutes(t);
|
||||||
|
const localMins = mins - offsetMinutes;
|
||||||
|
if (localMins < 0) return localMins + 24 * 60;
|
||||||
|
if (localMins >= 24 * 60) return localMins - 24 * 60;
|
||||||
|
return localMins;
|
||||||
|
}
|
||||||
|
|
||||||
function minutesToTop(minutes: number, startHour: number): number {
|
function minutesToTop(minutes: number, startHour: number): number {
|
||||||
return ((minutes - startHour * 60) / 60) * HOUR_HEIGHT;
|
return ((minutes - startHour * 60) / 60) * HOUR_HEIGHT;
|
||||||
}
|
}
|
||||||
@@ -127,6 +135,17 @@ function formatTime(t: string): string {
|
|||||||
return `${dh}:${String(m).padStart(2, '0')} ${period}`;
|
return `${dh}:${String(m).padStart(2, '0')} ${period}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTimeLocal(t: string, offsetMinutes: number): string {
|
||||||
|
const mins = timeToMinutes(t) - offsetMinutes;
|
||||||
|
let h = Math.floor(mins / 60) % 24;
|
||||||
|
if (h < 0) h += 24;
|
||||||
|
const m = mins % 60;
|
||||||
|
if (m < 0) m += 60;
|
||||||
|
const period = h >= 12 ? 'PM' : 'AM';
|
||||||
|
const dh = h > 12 ? h - 12 : h === 0 ? 12 : h;
|
||||||
|
return `${dh}:${String(m).padStart(2, '0')} ${period}`;
|
||||||
|
}
|
||||||
|
|
||||||
function addMinutesToTime(t: string, mins: number): string {
|
function addMinutesToTime(t: string, mins: number): string {
|
||||||
const [h, m] = t.split(':').map(Number);
|
const [h, m] = t.split(':').map(Number);
|
||||||
const total = h * 60 + m + mins;
|
const total = h * 60 + m + mins;
|
||||||
@@ -210,6 +229,7 @@ export default function RoutinesPage() {
|
|||||||
const [todayMeds, setTodayMeds] = useState<TodaysMedication[]>([]);
|
const [todayMeds, setTodayMeds] = useState<TodaysMedication[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [selectedDate, setSelectedDate] = useState(() => new Date());
|
const [selectedDate, setSelectedDate] = useState(() => new Date());
|
||||||
|
const [timezoneOffset, setTimezoneOffset] = useState(0);
|
||||||
const [nowMinutes, setNowMinutes] = useState(() => {
|
const [nowMinutes, setNowMinutes] = useState(() => {
|
||||||
const n = new Date();
|
const n = new Date();
|
||||||
return n.getHours() * 60 + n.getMinutes();
|
return n.getHours() * 60 + n.getMinutes();
|
||||||
@@ -230,7 +250,7 @@ export default function RoutinesPage() {
|
|||||||
|
|
||||||
const scheduledForDay = allSchedules
|
const scheduledForDay = allSchedules
|
||||||
.filter((s) => s.days.includes(dayKey))
|
.filter((s) => s.days.includes(dayKey))
|
||||||
.sort((a, b) => timeToMinutes(a.time) - timeToMinutes(b.time));
|
.sort((a, b) => timeToMinutesLocal(a.time, timezoneOffset) - timeToMinutesLocal(b.time, timezoneOffset));
|
||||||
|
|
||||||
const scheduledRoutineIds = new Set(allSchedules.map((s) => s.routine_id));
|
const scheduledRoutineIds = new Set(allSchedules.map((s) => s.routine_id));
|
||||||
const unscheduledRoutines = allRoutines.filter(
|
const unscheduledRoutines = allRoutines.filter(
|
||||||
@@ -298,8 +318,8 @@ export default function RoutinesPage() {
|
|||||||
// ── Dynamic time window ───────────────────────────────────────
|
// ── Dynamic time window ───────────────────────────────────────
|
||||||
const allEventMins = [
|
const allEventMins = [
|
||||||
nowMinutes,
|
nowMinutes,
|
||||||
...scheduledForDay.map((e) => timeToMinutes(e.time)),
|
...scheduledForDay.map((e) => timeToMinutesLocal(e.time, timezoneOffset)),
|
||||||
...groupedMedEntries.map((e) => timeToMinutes(e.time)),
|
...groupedMedEntries.map((e) => timeToMinutesLocal(e.time, timezoneOffset)),
|
||||||
];
|
];
|
||||||
const displayStartHour =
|
const displayStartHour =
|
||||||
allEventMins.length > 0
|
allEventMins.length > 0
|
||||||
@@ -420,11 +440,13 @@ export default function RoutinesPage() {
|
|||||||
api.routines.list(),
|
api.routines.list(),
|
||||||
api.routines.listAllSchedules(),
|
api.routines.listAllSchedules(),
|
||||||
api.medications.getToday().catch(() => []),
|
api.medications.getToday().catch(() => []),
|
||||||
|
api.preferences.get().catch(() => ({ timezone_offset: 0 })),
|
||||||
])
|
])
|
||||||
.then(([routines, schedules, meds]) => {
|
.then(([routines, schedules, meds, prefs]) => {
|
||||||
setAllRoutines(routines);
|
setAllRoutines(routines);
|
||||||
setAllSchedules(schedules);
|
setAllSchedules(schedules);
|
||||||
setTodayMeds(meds);
|
setTodayMeds(meds);
|
||||||
|
setTimezoneOffset((prefs as any).timezone_offset || 0);
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.finally(() => setIsLoading(false));
|
.finally(() => setIsLoading(false));
|
||||||
@@ -618,7 +640,7 @@ export default function RoutinesPage() {
|
|||||||
|
|
||||||
{/* Routine cards */}
|
{/* Routine cards */}
|
||||||
{scheduledForDay.map((entry) => {
|
{scheduledForDay.map((entry) => {
|
||||||
const startMin = timeToMinutes(entry.time);
|
const startMin = timeToMinutesLocal(entry.time, timezoneOffset);
|
||||||
const topPx = minutesToTop(startMin, displayStartHour);
|
const topPx = minutesToTop(startMin, displayStartHour);
|
||||||
const heightPx = durationToHeight(entry.total_duration_minutes);
|
const heightPx = durationToHeight(entry.total_duration_minutes);
|
||||||
const endMin = startMin + entry.total_duration_minutes;
|
const endMin = startMin + entry.total_duration_minutes;
|
||||||
@@ -656,16 +678,17 @@ export default function RoutinesPage() {
|
|||||||
{entry.routine_name}
|
{entry.routine_name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400 truncate">
|
<p className="text-xs text-gray-500 dark:text-gray-400 truncate">
|
||||||
{formatTime(entry.time)}
|
{formatTimeLocal(entry.time, timezoneOffset)}
|
||||||
{entry.total_duration_minutes > 0 && (
|
{entry.total_duration_minutes > 0 && (
|
||||||
<>
|
<>
|
||||||
{' '}
|
{' '}
|
||||||
-{' '}
|
-{' '}
|
||||||
{formatTime(
|
{formatTimeLocal(
|
||||||
addMinutesToTime(
|
addMinutesToTime(
|
||||||
entry.time,
|
entry.time,
|
||||||
entry.total_duration_minutes
|
entry.total_duration_minutes
|
||||||
)
|
),
|
||||||
|
timezoneOffset
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -627,6 +627,7 @@ export const api = {
|
|||||||
haptic_enabled: boolean;
|
haptic_enabled: boolean;
|
||||||
show_launch_screen: boolean;
|
show_launch_screen: boolean;
|
||||||
celebration_style: string;
|
celebration_style: string;
|
||||||
|
timezone_offset: number;
|
||||||
}>('/api/preferences', { method: 'GET' });
|
}>('/api/preferences', { method: 'GET' });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user