2026-07-11 23:37:48 +08:00

87 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from "next/link";
import { ChevronRight, PenLine, ScanLine } from "lucide-react";
import { PanelShell } from "@/components/panel-shell";
import { getCaregiverOverview } from "@/lib/caregiver-panel";
import { formatDateTime, getDeviceName, getMessageHref, truncateText } from "@/lib/panel-format";
import { requireCaregiverSession } from "@/lib/page-auth";
import { getCaregiverDisplayName } from "@/lib/session";
export const dynamic = "force-dynamic";
function greeting() {
const hour = new Date().getHours();
if (hour < 11) return "早上好";
if (hour < 14) return "中午好";
if (hour < 18) return "下午好";
return "晚上好";
}
export default async function Home() {
const caregiver = await requireCaregiverSession("/");
const { dashboard, recentIncomingMessages } = await getCaregiverOverview(caregiver.id);
const name = getCaregiverDisplayName(dashboard.caregiver);
const unreadIn = dashboard.devices.reduce((n, d) => n + d.elderUnreadCount, 0);
const unreadOut = dashboard.devices.reduce((n, d) => n + d.familyUnreadCount, 0);
const conversations = dashboard.devices.reduce((n, d) => n + d.elderDevice._count.conversationTurns, 0);
const date = new Intl.DateTimeFormat("zh-CN", { month: "numeric", day: "numeric", weekday: "short" }).format(new Date());
return (
<PanelShell
currentPath="/"
title={`${greeting()}${name}`}
description={`${date} · ${dashboard.devices.length} 台设备已连接`}
caregiverLabel={name}
unreadCount={unreadIn}
>
<section className="card">
{dashboard.devices.length ? dashboard.devices.map((binding) => (
<Link key={binding.id} href={`/devices/${binding.elderDevice.deviceUuid}`} className="list-row" style={{ alignItems: "center" }}>
<span className={`dot ${binding.elderDevice.lastSeenAt ? "online" : "offline"}`} style={{ marginTop: 0 }} />
<span className="row-title" style={{ flex: 1 }}>{getDeviceName(binding.alias, binding.elderDevice.displayName)}</span>
<span className="row-meta" style={{ marginTop: 0 }}>{binding.elderDevice.lastSeenAt ? "在线" : "未连接"}</span>
<ChevronRight size={14} color="var(--muted-light)" />
</Link>
)) : <div className="empty"></div>}
</section>
<section className="stats" style={{ gridTemplateColumns: "repeat(4,1fr)" }}>
<Link href="/messages" className="stat accent"><strong>{unreadIn}</strong><span></span></Link>
<Link href="/messages" className="stat"><strong>{unreadOut}</strong><span></span></Link>
<Link href="/activity" className="stat"><strong>{conversations}</strong><span></span></Link>
<Link href="/devices" className="stat"><strong>{dashboard.devices.length}</strong><span></span></Link>
</section>
<div className="button-row">
<Link href={dashboard.devices[0] ? `/devices/${dashboard.devices[0].elderDevice.deviceUuid}` : "/devices"} className="btn primary" style={{ flex: 1 }}>
<PenLine size={15} />
</Link>
<Link href="/scan" className="btn" style={{ flex: 1 }}><ScanLine size={15} /></Link>
</div>
<section>
<div className="section-title"><h2></h2><Link href="/messages"></Link></div>
<div className="card">
{recentIncomingMessages.length ? recentIncomingMessages.slice(0, 3).map((message) => (
<Link key={message.id} href={getMessageHref(message.publicId)} className="list-row">
<span className="dot" />
<span className="row-main">
<span className="row-title">{truncateText(message.content, 62)}</span>
<span className="row-meta">{message.importance !== "NORMAL" ? <span className="tag"></span> : null}{getDeviceName(message.elderDevice.displayName)} · {formatDateTime(message.createdAt)}</span>
</span>
</Link>
)) : <div className="empty"></div>}
</div>
</section>
<section>
<div className="section-title"><h2></h2><Link href="/activity"></Link></div>
<div className="card">
<div className="timeline-item"><div className="timeline-top"><span className="timeline-time"></span></div><p className="timeline-body">{dashboard.devices.length} </p></div>
<div className="timeline-item"><div className="timeline-top"><span className="timeline-time"></span></div><p className="timeline-body"> {conversations} </p></div>
</div>
</section>
</PanelShell>
);
}