MIRROR/src/app/page.tsx

130 lines
4.1 KiB
TypeScript
Raw Normal View History

2025-02-27 21:39:32 +08:00
"use client";
/**
2025-02-28 23:49:57 +08:00
* src\app\page.tsx
2025-02-27 21:39:32 +08:00
*
*/
import { useState, useEffect, useMemo } from "react";
import AnalogClock from "../components/AnalogClock";
import CalendarGrid from "../components/CalendarGrid";
import WeatherSection from "../components/WeatherSection";
import NewsSection from "../components/NewsSection";
import { generateCalendarDays } from "@/utils/calendar";
2025-02-28 23:28:56 +08:00
import { WeatherData, NewsItem, SunData } from "@/types/magic-mirror";
2025-02-27 21:39:32 +08:00
import VoiceAssistant from "@/components/VoiceAssistant";
import useSWR from "swr";
2025-02-28 23:28:56 +08:00
// 定义通用数据获取器
const fetcher = (url: string) => fetch(url).then((res) => res.json());
2025-02-27 21:39:32 +08:00
const MagicMirror = () => {
const [time, setTime] = useState(new Date());
const calendarDays = useMemo(() => generateCalendarDays(), []);
// 天气示例数据
2025-02-28 22:04:13 +08:00
const { data: weatherData, error: weatherError } = useSWR<WeatherData>(
"/api/weather",
(url: string) => fetch(url).then((res) => res.json())
);
2025-02-27 21:39:32 +08:00
// 新闻数据
const { data: newsItems = [], error: newsError } = useSWR<NewsItem[]>(
"/api/news",
(url: string) => fetch(url).then((res) => res.json())
);
2025-02-28 23:28:56 +08:00
// 在组件顶部新增SWR请求
// 日出日落数据
const { data: sunData = [] } = useSWR<SunData[]>("/api/sun", fetcher);
// 合并天气数据和日出日落数据
const mergedWeatherData = useMemo(() => {
if (weatherData && sunData.length > 0) {
return {
...weatherData,
sunrise: sunData[0]?.sunrise || "06:00",
sunset: sunData[0]?.sunset || "18:00",
};
}
return weatherData;
}, [weatherData, sunData]);
2025-02-27 21:39:32 +08:00
// 时间更新
useEffect(() => {
const timer = setInterval(() => setTime(new Date()), 1000);
return () => clearInterval(timer);
}, []);
// 生成问候语
const greeting = useMemo(() => {
const hours = time.getHours();
if (hours < 5) return "夜深了";
if (hours < 12) return "早上好";
if (hours < 18) return "下午好";
return "晚上好";
}, [time]);
2025-02-24 15:03:29 +08:00
return (
2025-02-27 21:39:32 +08:00
<div className="min-h-screen bg-black text-gray-100 font-sans antialiased overflow-hidden">
{/* 左上角时间模块 */}
<div className="absolute top-8 left-8 flex items-start gap-8">
{/* 时间日期模块 */}
<div className="space-y-1">
<div className="text-2xl font-light">
{time.toLocaleDateString("zh-CN", { weekday: "long" })}
</div>
<div className="text-gray-400 text-sm">
{time.toLocaleDateString("zh-CN", {
year: "numeric",
month: "long",
day: "numeric",
})}
</div>
<div className="flex items-end gap-2">
<div className="text-5xl font-light">
{time.toLocaleTimeString("zh-CN", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
})}
</div>
<div className="text-gray-400 mb-5">
{time.getSeconds().toString().padStart(2, "0")}
</div>
</div>
</div>
<AnalogClock time={time} />
</div>
2025-02-24 15:03:29 +08:00
2025-02-27 21:39:32 +08:00
{/* 日历模块 */}
<div className="absolute top-48 left-8 w-64">
<div className="mb-4 text-gray-300 text-sm">
{time.toLocaleDateString("zh-CN", { month: "long", year: "numeric" })}
2025-02-24 15:03:29 +08:00
</div>
2025-02-27 21:39:32 +08:00
<CalendarGrid days={calendarDays} />
</div>
{/* 分隔线 */}
<div className="absolute left-8 w-64 top-[420px] border-t border-white/10" />
{/* 待办事项 */}
<div className="absolute left-8 w-64 top-[460px] space-y-2 font-light">
<div className="text-gray-400 text-sm"></div>
<div className="text-gray-300 space-y-1">
<div> 10:00</div>
<div> </div>
<div> </div>
</div>
</div>
2025-02-28 23:28:56 +08:00
{/*<WeatherSection data={weatherData} />*/}
<WeatherSection data={mergedWeatherData} />
2025-02-27 21:39:32 +08:00
<NewsSection items={newsItems} />
<VoiceAssistant greeting={greeting} />
2025-02-24 15:03:29 +08:00
</div>
);
2025-02-27 21:39:32 +08:00
};
export default MagicMirror;