"use client"; import { useEffect, useId, useMemo, useRef, useState } from "react"; import { CaretDown, CaretLeft, CaretRight } from "@phosphor-icons/react"; import { minMothershipReadyDateIso, parseIsoDateLocal, } from "@/lib/mothership/logged-in-constraints"; import { buildMothershipWeekdayGrid, formatMothershipWeekdayDateLabel, monthLabelZh, } from "@/lib/mothership/weekday-date-picker"; import { quoteInputCls } from "@/components/quote/quote-form-chrome"; const WEEKDAYS_ZH = ["日", "一", "二", "三", "四", "五", "六"] as const; export type MothershipWeekdayDatePickerProps = { value: string; onChange: (iso: string) => void; disabled?: boolean; className?: string; minIso?: string; }; export function MothershipWeekdayDatePicker({ value, onChange, disabled, className, minIso = minMothershipReadyDateIso(), }: MothershipWeekdayDatePickerProps) { const rootRef = useRef(null); const listId = useId(); const [open, setOpen] = useState(false); const anchor = parseIsoDateLocal(value) ?? parseIsoDateLocal(minIso)!; const [viewYear, setViewYear] = useState(anchor.getFullYear()); const [viewMonth, setViewMonth] = useState(anchor.getMonth()); useEffect(() => { const d = parseIsoDateLocal(value); if (!d) return; setViewYear(d.getFullYear()); setViewMonth(d.getMonth()); }, [value]); useEffect(() => { if (!open) return; const onDoc = (e: MouseEvent) => { if (!rootRef.current?.contains(e.target as Node)) setOpen(false); }; document.addEventListener("mousedown", onDoc); return () => document.removeEventListener("mousedown", onDoc); }, [open]); const cells = useMemo( () => buildMothershipWeekdayGrid(viewYear, viewMonth, value, minIso), [viewYear, viewMonth, value, minIso], ); const shiftMonth = (delta: number) => { const d = new Date(viewYear, viewMonth + delta, 1, 12, 0, 0); setViewYear(d.getFullYear()); setViewMonth(d.getMonth()); }; return (
{open && !disabled && (
{monthLabelZh(viewYear, viewMonth)}
{WEEKDAYS_ZH.map((w) => (
{w}
))}
{cells.map((cell) => { const base = "flex h-9 w-9 items-center justify-center rounded-full text-sm transition-colors"; let cls = base; if (!cell.inMonth) { cls += " invisible pointer-events-none"; } else if (cell.disabled) { cls += " cursor-not-allowed text-text-disabled opacity-40"; } else if (cell.isSelected) { cls += " bg-[#1890FF] font-semibold text-white hover:bg-[#1580E0]"; } else { cls += " text-text-primary hover:bg-[#1890FF]/10 hover:text-[#1890FF]"; } return ( ); })}

周六、周日不可选

)}
); }