feat: add phone frequency controls and modularize codebase

This commit is contained in:
hectorzhao
2026-07-31 22:25:23 +08:00
parent 0af671b4ed
commit ca4f591a13
216 changed files with 41579 additions and 23694 deletions
+21 -2
View File
@@ -17,6 +17,17 @@ function formatDate(date: Date) {
return `${year}-${month}-${day}`;
}
function shanghaiDate() {
const parts = new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).formatToParts(new Date());
const values = new Map(parts.map((part) => [part.type, part.value]));
return `${values.get('year')}-${values.get('month')}-${values.get('day')}`;
}
function parseDate(value?: string) {
if (!value) {
return undefined;
@@ -55,8 +66,9 @@ function splitDateTime(value: string) {
export function DateTimeInput({ label, value, onChange, placeholder = '选择定时发送时间' }: DateTimeInputProps) {
const { date, time } = splitDateTime(value);
const today = shanghaiDate();
const [open, setOpen] = useState(false);
const [viewDate, setViewDate] = useState(() => parseDate(date) ?? new Date());
const [viewDate, setViewDate] = useState(() => parseDate(date) ?? parseDate(today) ?? new Date());
const calendarDays = useMemo(() => getCalendarDays(viewDate), [viewDate]);
function moveMonth(offset: number) {
@@ -68,7 +80,12 @@ export function DateTimeInput({ label, value, onChange, placeholder = '选择定
}
function updateTime(nextTime: string) {
onChange(`${date || formatDate(new Date())}T${nextTime}`);
onChange(`${date || today}T${nextTime}`);
}
function selectToday() {
setViewDate(parseDate(today) ?? new Date());
updateDate(today);
}
return (
@@ -117,6 +134,7 @@ export function DateTimeInput({ label, value, onChange, placeholder = '选择定
className={[
'ui-calendar__day',
item.inCurrentMonth ? '' : 'ui-calendar__day--muted',
item.dateString === today ? 'ui-calendar__day--today' : '',
item.dateString === date ? 'ui-calendar__day--selected' : '',
].filter(Boolean).join(' ')}
key={item.dateString}
@@ -134,6 +152,7 @@ export function DateTimeInput({ label, value, onChange, placeholder = '选择定
</label>
<div className="ui-date-range-actions">
<button onClick={() => onChange('')} type="button"></button>
<button onClick={selectToday} type="button"></button>
<button disabled={!value} onClick={() => setOpen(false)} type="button"></button>
</div>
</div>