用途:这是 Dink Derby 项目的客户端开发技能,指导在 React/Vite 前端中构建 UI 组件、实现本地优先(local-first)数据模式与离线同步。
技术栈:框架为 React 18 + Vite;本地数据库为 Dexie(IndexedDB 封装,见 src/db.ts);样式使用 Tailwind CSS;类型从 @dink-derby/shared-types 导入。
本地优先流程:所有数据操作先写入本地(立即更新 Dexie),再向 syncOutbox 表加入待同步条目,UI 始终从 Dexie 读取,联网时后台 POST 到 /sync。
Dexie 表:users、derbies、derbyParticipants、catches、chatMessages、syncOutbox(待处理操作)、device(本地设备身份)。syncOutbox 条目包含 id、entityType、entityId、operation(create/update/delete)、payload、createdAt。
组件模式:新组件放在 src/components/,用 useLiveQuery 等 Dexie hooks 获取响应式数据,处理加载与错误状态,参考 DerbyList.tsx、LogCatchForm.tsx。表单提交时用 crypto.randomUUID() 生成 id,写入对应表并同步加入 syncOutbox。
UX 规则(不可妥协):目标用户是电量 7%、烈日下眯眼用手机的人。点击目标最小 44x44px,文字大且阳光下可读,导航极简(记录渔获单屏完成),清晰显示离线/同步状态且不阻塞操作,本地写入即时反馈。Add Catch 单屏包含物种(可选文本)、测量值(随 derby 的 scoringMode 变化)、可选照片和提交按钮。
文件结构:src/App.tsx(路由/布局)、src/db.ts(Dexie 设置)、src/components/、src/sync/、src/utils/。
测试:组件旁放单元测试 Component.test.tsx,测试配置在 src/test/setup.ts,E2E 用 Playwright 放在 e2e/。
新增实体类型步骤:在 packages/shared-types 加 Zod schema,在 src/db.ts 加 Dexie 表,在 src/components/ 建组件,加入 sync outbox 处理。离线状态可用 navigator.onLine 判断,离线时显示横幅但不阻塞用户操作。
限制:资料未提供安装命令、依赖版本细节、部署方式及收费信息。