125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Input } from "@/components/ui/input"
|
|
import { Label } from "@/components/ui/label"
|
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
|
import { solar2lunar, parseDate } from "@/lib/lunar-calendar"
|
|
import { Calendar } from "lucide-react"
|
|
|
|
interface DateInputWithLunarProps {
|
|
label: string
|
|
value?: string
|
|
isLunar?: boolean
|
|
onChange: (value: string) => void
|
|
onLunarChange?: (isLunar: boolean) => void
|
|
id?: string
|
|
showLunarToggle?: boolean // 是否显示公历/农历切换
|
|
}
|
|
|
|
export function DateInputWithLunar({
|
|
label,
|
|
value,
|
|
isLunar = false,
|
|
onChange,
|
|
onLunarChange,
|
|
id,
|
|
showLunarToggle = true,
|
|
}: DateInputWithLunarProps) {
|
|
const [lunarInfo, setLunarInfo] = useState<string>("")
|
|
|
|
// 当日期改变时,更新农历信息
|
|
useEffect(() => {
|
|
if (!value) {
|
|
setLunarInfo("")
|
|
return
|
|
}
|
|
|
|
const date = parseDate(value)
|
|
if (!date) {
|
|
setLunarInfo("")
|
|
return
|
|
}
|
|
|
|
try {
|
|
const lunar = solar2lunar(date)
|
|
if (lunar) {
|
|
setLunarInfo(lunar.toString())
|
|
} else {
|
|
const year = date.getFullYear()
|
|
setLunarInfo(`⚠️ 农历转换仅支持1900-2100年 (当前: ${year}年)`)
|
|
}
|
|
} catch (error) {
|
|
console.error("日期转换错误:", error)
|
|
setLunarInfo("")
|
|
}
|
|
}, [value])
|
|
|
|
return (
|
|
<div className="space-y-3">
|
|
<Label htmlFor={id} className="text-base font-medium">
|
|
{label}
|
|
</Label>
|
|
|
|
{/* 公历日期输入 */}
|
|
<div className="relative">
|
|
<Input
|
|
id={id}
|
|
type="date"
|
|
value={value || ""}
|
|
onChange={(e) => onChange(e.target.value)}
|
|
className="pr-10"
|
|
/>
|
|
<Calendar className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
|
|
</div>
|
|
|
|
{/* 农历对照显示 */}
|
|
{lunarInfo && (
|
|
<div className="bg-amber-50 border border-amber-200 rounded-lg p-3">
|
|
<div className="flex items-start gap-2">
|
|
<Calendar className="h-4 w-4 text-amber-600 mt-0.5 flex-shrink-0" />
|
|
<div className="flex-1 space-y-1">
|
|
<div className="text-sm font-medium text-amber-900">
|
|
农历对照
|
|
</div>
|
|
<div className="text-sm text-amber-800">
|
|
{lunarInfo}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 纪念日类型选择 */}
|
|
{showLunarToggle && value && lunarInfo && !lunarInfo.includes('⚠️') && onLunarChange && (
|
|
<div className="space-y-2">
|
|
<Label className="text-sm font-medium">纪念日计算方式</Label>
|
|
<RadioGroup
|
|
value={isLunar ? "lunar" : "solar"}
|
|
onValueChange={(val) => onLunarChange(val === "lunar")}
|
|
className="flex flex-row gap-6"
|
|
>
|
|
<div className="flex items-center space-x-2">
|
|
<RadioGroupItem value="solar" id={`${id}-solar`} />
|
|
<Label htmlFor={`${id}-solar`} className="text-sm font-normal cursor-pointer">
|
|
按公历 (每年固定日期)
|
|
</Label>
|
|
</div>
|
|
<div className="flex items-center space-x-2">
|
|
<RadioGroupItem value="lunar" id={`${id}-lunar`} />
|
|
<Label htmlFor={`${id}-lunar`} className="text-sm font-normal cursor-pointer">
|
|
按农历 (对应农历日期)
|
|
</Label>
|
|
</div>
|
|
</RadioGroup>
|
|
<p className="text-xs text-muted-foreground">
|
|
{isLunar
|
|
? "💡 将按农历日期计算每年的纪念日,如生日、祭日等"
|
|
: "💡 将按公历日期计算每年的纪念日"}
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|