| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { CalendarIcon } from 'lucide-react';
- import type { FunnelPeriod } from '../../../api/types';
- import { toSnapshotParam, yesterday } from '../period';
- import { Calendar } from '@/components/ui/calendar';
- import {
- Popover,
- PopoverContent,
- PopoverTrigger,
- } from '@/components/ui/popover';
- import { cn } from '@/lib/utils';
- interface Props {
- period: FunnelPeriod;
- /** Selected day for `period: 'day'`. */
- snapshotDt: Date;
- /** Pick a historical day → switch to single-day mode. */
- onPickDate: (d: Date) => void;
- /** Pick a rolling window. */
- onPickRolling: (p: 'last_7d' | 'last_30d') => void;
- }
- // 统一 segmented:选中态由 React 状态直接驱动 mint 实色,不依赖 shadcn 变体。
- const SEG =
- 'h-8 px-3 inline-flex items-center gap-1.5 rounded-md text-sm font-medium transition-colors cursor-pointer';
- const ON = 'bg-primary text-primary-foreground shadow-sm';
- const OFF = 'text-muted-foreground hover:text-foreground hover:bg-background';
- /**
- * 时间选择 — 单日 / 近 7 天 / 近 30 天 三选一的 segmented 控件(docs/04)。
- * 「单日」段点开日历可选历史日(上限昨日,T+1);任一选中 = mint 高亮,
- * 给明确的"当前在此周期"反馈。
- */
- export function TimePeriodSelect({
- period,
- snapshotDt,
- onPickDate,
- onPickRolling,
- }: Props) {
- const max = yesterday();
- return (
- <div className="inline-flex items-center gap-1 rounded-lg border border-border bg-muted/60 p-1">
- {/* 单日 —— 日历 popover */}
- <Popover>
- <PopoverTrigger asChild>
- <button
- type="button"
- aria-label="选择历史日期"
- aria-pressed={period === 'day'}
- className={cn(SEG, period === 'day' ? ON : OFF)}
- >
- <CalendarIcon className="size-4" />
- <span>单日</span>
- <span className="tabular-nums opacity-90">
- {toSnapshotParam(snapshotDt)}
- </span>
- </button>
- </PopoverTrigger>
- <PopoverContent className="w-auto p-0" align="start">
- <Calendar
- mode="single"
- selected={snapshotDt}
- defaultMonth={snapshotDt}
- disabled={{ after: max }}
- required
- onSelect={(d) => {
- if (d) onPickDate(d);
- }}
- />
- </PopoverContent>
- </Popover>
- {/* 近 7 天 / 近 30 天 */}
- <button
- type="button"
- aria-pressed={period === 'last_7d'}
- onClick={() => onPickRolling('last_7d')}
- className={cn(SEG, period === 'last_7d' ? ON : OFF)}
- >
- 近 7 天
- </button>
- <button
- type="button"
- aria-pressed={period === 'last_30d'}
- onClick={() => onPickRolling('last_30d')}
- className={cn(SEG, period === 'last_30d' ? ON : OFF)}
- >
- 近 30 天
- </button>
- </div>
- );
- }
- export default TimePeriodSelect;
|