feat(reminders): custom date/time option in Remind Me
The Remind Me dialog only offered four fixed presets, so you couldn't set a reminder for an arbitrary time. Add a "Custom time…" option that reveals date + time pickers (validated >= 1 minute in the future) and sets the reminder at that absolute timestamp. Also extract the local date/time <input> helpers (toLocalDate, toLocalTime, parseLocalDateTime, pickerInputStyle) into a shared, unit-tested utils/datetimeInput.ts and reuse them in ScheduleMessageModal (deduped from an inline copy) — identical output, now covered by tests. Documents the previously-undocumented Message Reminders feature in LOTUS_FEATURES.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { CSSProperties } from 'react';
|
||||
import { color as foldsColor, config as foldsConfig } from 'folds';
|
||||
|
||||
const pad = (n: number): string => String(n).padStart(2, '0');
|
||||
|
||||
// Format a Date as the value string expected by <input type="date"> in the
|
||||
// user's LOCAL timezone. (toISOString would shift to UTC and can land on the
|
||||
// wrong calendar day.)
|
||||
export function toLocalDate(date: Date): string {
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
||||
}
|
||||
|
||||
// Format a Date as the value string expected by <input type="time"> (local, HH:mm).
|
||||
export function toLocalTime(date: Date): string {
|
||||
return `${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
||||
}
|
||||
|
||||
// Parse the local date + time <input> values back into a Date. Returns null when
|
||||
// either value is missing or the combination is invalid (e.g. a partial entry).
|
||||
export function parseLocalDateTime(dateValue: string, timeValue: string): Date | null {
|
||||
if (!dateValue || !timeValue) return null;
|
||||
const dt = new Date(`${dateValue}T${timeValue}:00`);
|
||||
return Number.isNaN(dt.getTime()) ? null : dt;
|
||||
}
|
||||
|
||||
// Shared style for date/time <input>s — matches the app's surface tokens and
|
||||
// hints a dark-mode calendar/clock popup via colorScheme.
|
||||
export function pickerInputStyle(
|
||||
c: typeof foldsColor = foldsColor,
|
||||
cfg: typeof foldsConfig = foldsConfig,
|
||||
): CSSProperties {
|
||||
return {
|
||||
background: c.SurfaceVariant.Container,
|
||||
color: c.SurfaceVariant.OnContainer,
|
||||
border: `${cfg.borderWidth.B300} solid ${c.SurfaceVariant.ContainerLine}`,
|
||||
borderRadius: cfg.radii.R300,
|
||||
padding: `${cfg.space.S200} ${cfg.space.S300}`,
|
||||
fontSize: '0.875rem',
|
||||
width: '100%',
|
||||
boxSizing: 'border-box',
|
||||
outline: 'none',
|
||||
fontFamily: 'inherit',
|
||||
colorScheme: 'dark',
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user