147 lines
6.6 KiB
TypeScript
147 lines
6.6 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Calendar as CalendarIcon } from "lucide-react"
|
|
import { Button } from "@/components/ui/button"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog"
|
|
import { solar2lunar, formatDate } from "@/lib/lunar-calendar"
|
|
import dynamic from 'next/dynamic'
|
|
|
|
// 动态导入 Ant Design 日历组件(避免 SSR 问题)
|
|
const AntdLunarCalendar = dynamic(
|
|
() => import('@/components/antd-lunar-calendar').then(mod => ({ default: mod.AntdLunarCalendar })),
|
|
{ ssr: false, loading: () => <div className="h-[400px] flex items-center justify-center">加载中...</div> }
|
|
)
|
|
|
|
interface CalendarDialogProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
}
|
|
|
|
export function CalendarDialog({ open, onOpenChange }: CalendarDialogProps) {
|
|
const [selectedDate, setSelectedDate] = useState<Date>(new Date())
|
|
|
|
// 获取农历信息
|
|
const lunarInfo = solar2lunar(selectedDate)
|
|
|
|
// 格式化显示
|
|
const solarStr = formatDate(selectedDate)
|
|
const [year, monthNum, day] = solarStr.split('-')
|
|
const weekDay = ['日', '一', '二', '三', '四', '五', '六'][selectedDate.getDay()]
|
|
|
|
// 当对话框打开时,重置为当前日期
|
|
useEffect(() => {
|
|
if (open) {
|
|
const now = new Date()
|
|
setSelectedDate(now)
|
|
}
|
|
}, [open])
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="max-w-4xl w-[90vw] max-h-[90vh] overflow-y-auto" aria-describedby={undefined}>
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2 text-2xl font-serif">
|
|
<CalendarIcon className="h-6 w-6 text-red-600" />
|
|
公历农历查询
|
|
</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-6">
|
|
{/* Ant Design 日历 */}
|
|
<div className="space-y-4">
|
|
<AntdLunarCalendar onSelect={(date) => setSelectedDate(date)} />
|
|
</div>
|
|
|
|
{/* 日期信息卡片 - 美化版 */}
|
|
<div className="grid md:grid-cols-2 gap-6">
|
|
{/* 公历信息 */}
|
|
<div className="group relative rounded-2xl border-2 border-blue-300/50 bg-gradient-to-br from-blue-50 via-sky-50 to-blue-100 p-6 shadow-lg hover:shadow-xl transition-all duration-300 overflow-hidden">
|
|
{/* 装饰性背景 */}
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-200/20 rounded-full -mr-16 -mt-16 group-hover:scale-110 transition-transform duration-500"></div>
|
|
<div className="absolute bottom-0 left-0 w-24 h-24 bg-sky-200/20 rounded-full -ml-12 -mb-12 group-hover:scale-110 transition-transform duration-500"></div>
|
|
|
|
<div className="relative z-10">
|
|
<div className="flex items-center gap-2 mb-4">
|
|
<div className="h-2 w-2 rounded-full bg-blue-600 animate-pulse"></div>
|
|
<h3 className="text-sm font-semibold text-blue-900 tracking-wide">公历 SOLAR</h3>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<div className="text-2xl font-bold text-blue-900 font-serif leading-tight">
|
|
{year}年
|
|
</div>
|
|
<div className="text-3xl font-bold text-blue-900 font-serif leading-tight tracking-tight">
|
|
{parseInt(monthNum)}月{parseInt(day)}日
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<div className="px-3 py-1 rounded-lg bg-blue-600/10 border border-blue-300/50">
|
|
<span className="text-sm text-blue-800 font-medium">星期{weekDay}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 农历信息 */}
|
|
{lunarInfo ? (
|
|
<div className="group relative rounded-2xl border-2 border-red-300/50 bg-gradient-to-br from-red-50 via-orange-50 to-amber-100 p-6 shadow-lg hover:shadow-xl transition-all duration-300 overflow-hidden">
|
|
{/* 装饰性背景 */}
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-red-200/20 rounded-full -mr-16 -mt-16 group-hover:scale-110 transition-transform duration-500"></div>
|
|
<div className="absolute bottom-0 left-0 w-24 h-24 bg-amber-200/20 rounded-full -ml-12 -mb-12 group-hover:scale-110 transition-transform duration-500"></div>
|
|
|
|
<div className="relative z-10">
|
|
<div className="flex items-center gap-2 mb-4">
|
|
<div className="h-2 w-2 rounded-full bg-red-600 animate-pulse"></div>
|
|
<h3 className="text-sm font-semibold text-red-900 tracking-wide">农历 LUNAR</h3>
|
|
</div>
|
|
<div className="space-y-3">
|
|
<div className="text-2xl font-bold text-red-900 font-serif leading-tight">
|
|
{lunarInfo.ganZhiYear}年
|
|
</div>
|
|
<div className="text-xl font-semibold text-red-800 font-serif">
|
|
{lunarInfo.monthName}{lunarInfo.dayName}
|
|
</div>
|
|
<div className="flex items-center gap-2 flex-wrap">
|
|
<span className="px-3 py-1 rounded-lg bg-red-600/10 border border-red-300/50 text-sm text-red-800 font-medium">
|
|
{lunarInfo.animal}年
|
|
</span>
|
|
{lunarInfo.isLeap && (
|
|
<span className="px-3 py-1 rounded-lg bg-amber-500/20 border border-amber-400/50 text-sm text-amber-800 font-medium flex items-center gap-1">
|
|
<span className="text-xs">✦</span> 闰月
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="rounded-2xl border-2 border-gray-300/50 bg-gradient-to-br from-gray-50 to-gray-100 p-6 shadow-lg flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-4xl mb-2">📅</div>
|
|
<div className="text-gray-600 font-medium">农历信息不可用</div>
|
|
<div className="text-xs text-gray-500 mt-1">日期超出范围 (1900-2100)</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* 今天按钮 */}
|
|
<div className="flex justify-center">
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setSelectedDate(new Date())}
|
|
>
|
|
返回今天
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|