147 lines
7.0 KiB
TypeScript
147 lines
7.0 KiB
TypeScript
import Link from "next/link";
|
||
|
||
import { BindDeviceForm } from "@/components/dashboard-actions";
|
||
import { PanelShell } from "@/components/panel-shell";
|
||
import { PwaControls } from "@/components/pwa-controls";
|
||
import { getCaregiverDevices } from "@/lib/caregiver-panel";
|
||
import { formatDateTime, getDeviceName, truncateText } from "@/lib/panel-format";
|
||
import { requireCaregiverSession } from "@/lib/page-auth";
|
||
import { getCaregiverDisplayName } from "@/lib/session";
|
||
|
||
export const dynamic = "force-dynamic";
|
||
|
||
export default async function DevicesPage() {
|
||
const caregiver = await requireCaregiverSession("/devices");
|
||
const devices = await getCaregiverDevices(caregiver.id);
|
||
|
||
return (
|
||
<PanelShell
|
||
currentPath="/devices"
|
||
title="我的设备"
|
||
description="管理已连接的长辈设备,点击进入设备详情查看留言和使用动态。"
|
||
caregiverLabel={getCaregiverDisplayName(caregiver)}
|
||
actions={<PwaControls />}
|
||
>
|
||
<section className="grid gap-6 xl:grid-cols-[0.95fr_1.05fr]">
|
||
<BindDeviceForm />
|
||
|
||
<div className="rounded-[32px] border border-white/75 bg-white/82 p-6 shadow-[0_26px_60px_rgba(115,76,42,0.12)]">
|
||
<p className="text-sm font-medium tracking-[0.18em] text-[var(--copper)] uppercase">
|
||
使用说明
|
||
</p>
|
||
<h2 className="mt-2 font-[family-name:var(--font-display)] text-3xl text-[var(--ink)]">
|
||
如何连接长辈的设备?
|
||
</h2>
|
||
<div className="mt-4 space-y-3 rounded-[24px] bg-[var(--paper-soft)] p-5 text-sm leading-7 text-[var(--muted)]">
|
||
<p>1. 让长辈打开手机上的「家人连接」页面,屏幕会显示一个二维码。</p>
|
||
<p>2. 您用自己的手机扫描这个二维码,或将设备码粘贴到左侧输入框。</p>
|
||
<p>3. 连接成功后,即可在这里查看长辈的留言、对话和使用动态。</p>
|
||
</div>
|
||
|
||
<div className="mt-6 flex flex-wrap gap-3">
|
||
<Link
|
||
href="/scan"
|
||
className="inline-flex h-12 items-center justify-center rounded-full bg-[var(--olive)] px-5 text-sm font-semibold text-white transition hover:bg-[var(--olive-deep)]"
|
||
>
|
||
扫码连接
|
||
</Link>
|
||
<Link
|
||
href="/messages"
|
||
className="inline-flex h-12 items-center justify-center rounded-full border border-[var(--line)] bg-white px-5 text-sm font-semibold text-[var(--ink)] transition hover:bg-[var(--paper-soft)]"
|
||
>
|
||
查看留言
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{devices.length === 0 ? (
|
||
<section className="rounded-[32px] border border-dashed border-[var(--line)] bg-white/72 px-6 py-10 text-center shadow-[0_20px_50px_rgba(115,76,42,0.10)]">
|
||
<h2 className="font-[family-name:var(--font-display)] text-3xl text-[var(--ink)]">
|
||
还没有连接设备
|
||
</h2>
|
||
<p className="mx-auto mt-4 max-w-2xl text-base leading-8 text-[var(--muted)]">
|
||
扫描长辈手机上的二维码,或者在上方粘贴设备码,即可开始接收长辈的留言和动态。
|
||
</p>
|
||
</section>
|
||
) : (
|
||
<section className="grid gap-6 lg:grid-cols-2">
|
||
{devices.map((binding) => {
|
||
const latestMessage = binding.elderDevice.messages[0];
|
||
|
||
return (
|
||
<article
|
||
key={binding.id}
|
||
className="rounded-[32px] border border-white/75 bg-white/82 p-6 shadow-[0_26px_60px_rgba(115,76,42,0.12)]"
|
||
>
|
||
<p className="text-sm font-medium tracking-[0.18em] text-[var(--copper)] uppercase">
|
||
已连接
|
||
</p>
|
||
<h2 className="mt-2 font-[family-name:var(--font-display)] text-3xl text-[var(--ink)]">
|
||
{getDeviceName(binding.elderDevice.displayName)}
|
||
</h2>
|
||
|
||
<div className="mt-4 flex flex-wrap gap-3 text-sm text-[var(--muted)]">
|
||
<span className="rounded-full border border-[var(--line)] bg-[var(--paper-soft)] px-4 py-2">
|
||
最近在线:{formatDateTime(binding.elderDevice.lastSeenAt)}
|
||
</span>
|
||
<span className="rounded-full border border-[var(--line)] bg-[var(--paper-soft)] px-4 py-2">
|
||
新留言 {binding.elderUnreadCount}
|
||
</span>
|
||
<span className="rounded-full border border-[var(--line)] bg-[var(--paper-soft)] px-4 py-2">
|
||
待查看 {binding.familyUnreadCount}
|
||
</span>
|
||
</div>
|
||
|
||
<div className="mt-5 grid gap-3 sm:grid-cols-3">
|
||
<div className="rounded-[22px] bg-[var(--paper-soft)] px-4 py-4">
|
||
<p className="text-xs text-[var(--muted)]">留言</p>
|
||
<p className="mt-2 text-2xl font-semibold text-[var(--ink)]">
|
||
{binding.elderDevice._count.messages}
|
||
</p>
|
||
</div>
|
||
<div className="rounded-[22px] bg-[var(--paper-soft)] px-4 py-4">
|
||
<p className="text-xs text-[var(--muted)]">对话</p>
|
||
<p className="mt-2 text-2xl font-semibold text-[var(--ink)]">
|
||
{binding.elderDevice._count.conversationTurns}
|
||
</p>
|
||
</div>
|
||
<div className="rounded-[22px] bg-[var(--paper-soft)] px-4 py-4">
|
||
<p className="text-xs text-[var(--muted)]">智能服务</p>
|
||
<p className="mt-2 text-2xl font-semibold text-[var(--ink)]">
|
||
{binding.elderDevice._count.toolCalls}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-5 rounded-[24px] bg-[var(--paper-soft)] px-5 py-4">
|
||
<p className="text-sm font-semibold text-[var(--ink)]">最新动态</p>
|
||
<p className="mt-2 text-sm leading-7 text-[var(--muted)]">
|
||
{latestMessage
|
||
? truncateText(latestMessage.content, 96)
|
||
: "还没有收到新的留言或问候。"}
|
||
</p>
|
||
</div>
|
||
|
||
<div className="mt-6 flex flex-wrap gap-3">
|
||
<Link
|
||
href={`/devices/${binding.elderDevice.deviceUuid}`}
|
||
className="inline-flex h-12 items-center justify-center rounded-full bg-[var(--copper)] px-5 text-sm font-semibold text-white transition hover:bg-[var(--copper-deep)]"
|
||
>
|
||
查看详情
|
||
</Link>
|
||
<Link
|
||
href="/messages"
|
||
className="inline-flex h-12 items-center justify-center rounded-full border border-[var(--line)] bg-white px-5 text-sm font-semibold text-[var(--ink)] transition hover:bg-[var(--paper-soft)]"
|
||
>
|
||
查看留言
|
||
</Link>
|
||
</div>
|
||
</article>
|
||
);
|
||
})}
|
||
</section>
|
||
)}
|
||
</PanelShell>
|
||
);
|
||
} |