"use client"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { startTransition, useState } from "react"; export function BindDeviceForm() { const router = useRouter(); const [rawCode, setRawCode] = useState(""); const [submitting, setSubmitting] = useState(false); const [notice, setNotice] = useState(null); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!rawCode.trim()) { setNotice("先把老人二维码里的设备码贴进来。\n"); return; } setSubmitting(true); setNotice("正在建立连接,请稍候……"); try { const response = await fetch("/api/family/bind", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ deviceUuid: rawCode }), }); const payload = (await response.json().catch(() => null)) as | { error?: string } | null; if (!response.ok) { throw new Error(payload?.error || "连接失败,请稍后再试。"); } setNotice("已经连上了,这位老人的留言和陪伴记录会出现在下方。\n"); setRawCode(""); startTransition(() => { router.refresh(); }); } catch (error) { setNotice( error instanceof Error ? error.message : "连接失败,请稍后再试。", ); } finally { setSubmitting(false); } } return (

家人连接

扫二维码,或者直接贴入设备码

如果老人已经把二维码发给您,直接扫码最快;如果您拿到的是一段链接或设备码,也可以贴到下面。

打开扫码页
setRawCode(event.target.value)} placeholder="粘贴二维码链接,或者直接贴设备 UUID" className="h-13 flex-1 rounded-full border border-[var(--line)] bg-[var(--paper-soft)] px-5 text-sm text-[var(--ink)] outline-none transition focus:border-[var(--copper)] focus:bg-white" />
{notice ? (

{notice}

) : null}
); } type SendMessageFormProps = { deviceUuid: string; }; export function SendMessageForm({ deviceUuid }: SendMessageFormProps) { const router = useRouter(); const [content, setContent] = useState(""); const [importance, setImportance] = useState("NORMAL"); const [submitting, setSubmitting] = useState(false); const [notice, setNotice] = useState(null); const [createdMessagePublicId, setCreatedMessagePublicId] = useState(null); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!content.trim()) { setNotice("先写下想对老人说的话。\n"); setCreatedMessagePublicId(null); return; } setSubmitting(true); setNotice("正在送达这条留言……"); try { const response = await fetch("/api/family/messages", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ deviceUuid, content, importance, }), }); const payload = (await response.json().catch(() => null)) as | { error?: string; publicId?: number } | null; if (!response.ok) { throw new Error(payload?.error || "留言发送失败,请稍后再试。"); } setNotice("留言已经写进家人的收件盒,老人下次打开或询问时就能看到。\n"); setCreatedMessagePublicId( typeof payload?.publicId === "number" ? payload.publicId : null, ); setContent(""); setImportance("NORMAL"); startTransition(() => { router.refresh(); }); } catch (error) { setCreatedMessagePublicId(null); setNotice( error instanceof Error ? error.message : "留言发送失败,请稍后再试。", ); } finally { setSubmitting(false); } } return (

给老人留句话

写一句今天就能被看到的问候