其他
在 Caffeine AI 中需要管理员生成邀请链接…
适用于 Caffeine AI 应用需要邀请码/RSVP 收集,管理员登录查看回复、访客无需登录提交回复的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 40/100 ×0.15
适用场景
在 Caffeine AI 中需要管理员特定
解决思路
- 使用预制模块 `mo:caffeineai-invite-links/invite-links-module.mo` 提供底层邀请链接和 RSVP 状态管理。
- 不要修改预制模块 `invite-links-module.mo`。
- 使用模块中的 `RSVP` 类型:`name : Text`、`attending : Bool`、`timestamp : Time.Time`、`inviteCode : Text`。
- 使用模块中的 `InviteCode` 类型:`code : Text`、`created : Time.Time`、`used : Bool`。
- 使用模块中的 `InviteLinksSystemState`,它包含 `var rsvps : Map.Map<Text, RSVP>` 和 `var inviteCodes : Map.Map<Text, InviteCode>`。
- 调用 `initState()` 初始化邀请链接系统状态。
- 调用 `generateUUID(blob)` 生成 UUID。
- 调用 `generateInviteCode(state, code)` 生成邀请码。
- 调用 `getInviteCodes(state)` 获取邀请码列表。
- 调用 `submitRSVP(state, name, attending, inviteCode)` 提交 RSVP。
- 调用 `getAllRSVPs(state)` 获取所有 RSVP。
- 在 `main.mo` 中放置 `include MixinInviteLinks(accessControlState, inviteState)`,不能放在自定义 mixin 文件里。
- 不要重新声明 `generateInviteCode()`、`submitRSVP(name, attending, inviteCode)`、`getAllRSVPs()`、`getInviteCodes()`;它们由 `MixinInviteLinks` 独家提供。
- 在 `main.mo` 中导入 `AccessControl`、`MixinAuthorization`、`MixinInviteLinks`、`InviteLinksModule`。
- 在 actor 中声明 `let accessControlState : AccessControl.AccessControlState;`,并 `include MixinAuthorization(accessControlState, null);`。
- 在 actor 中声明 `let inviteState : InviteLinksModule.InviteLinksSystemState;`,并 `include MixinInviteLinks(accessControlState, inviteState);`。
- 在 include 之后写额外的应用特定代码。
- 在迁移链头 `src/backend/migrations/00000000_000000.mo` 中导入 `AccessControl` 和 `InviteLinksModule`。
- 在迁移文件中定义 `NewActor` 类型,包含 `accessControlState : AccessControl.AccessControlState;` 和 `inviteState : InviteLinksModule.InviteLinksSystemState;`。
- 实现 `public func migration(_old : {}) : NewActor`,返回 `{ accessControlState = AccessControl.initState(); inviteState = InviteLinksModule.initState(); }`。
- 在前端实现 Internet Identity 认证,并支持管理员专用邀请链接/RSVP。
- 在 `src/App.tsx` 中导入 `AdminDashboard`、`GuestRSVP`、`LoginButton`、`useIsCurrentUserAdmin`。
- 用 `useIsCurrentUserAdmin()` 获取 `isAdmin`,根据 `isAdmin` 渲染 `<AdminDashboard />` 或 `<GuestRSVP />`,并渲染 `<LoginButton />`。
- 在 `src/components/GuestRSVP.tsx` 中用 `useState` 管理 `name`、`inviteCode`、`attending`、`submitted`,并使用 `useSubmitRSVP()`。
- 在 `useEffect` 中从 `new URLSearchParams(window.location.search).get('code')` 读取邀请码,存在则设置 `inviteCode`。
- 提交表单时调用 `submitRSVP.mutate({ name, attending, inviteCode }, { onSuccess: () => setSubmitted(true) })`。
- 提交成功后显示感谢信息;表单包含姓名输入、邀请码输入、出席/不出席单选;提交按钮根据 `submitRSVP.isPending` 禁用;错误时显示 `submitRSVP.error.message`。
- 在 `src/components/AdminDashboard.tsx` 中使用 `useGetAllRSVPs()`、`useGetInviteCodes()`、`useGenerateInviteCode()`。
- 过滤未使用邀请码:`inviteCodes?.filter(code => !code.used)`;统计总 RSVP、出席人数、不出席人数。
- 提供“生成新邀请码”按钮,点击调用 `generateInviteCode.mutate()`。
- 显示未使用邀请码,并提供复制链接按钮,复制 `${window.location.origin}?code=${code.code}` 到剪贴板。
- 显示 RSVP 表格,列为 Name、Status、Date;日期使用 `new Date(Number(rsvp.timestamp / BigInt(1000000))).toLocaleDateString()` 转换 `timestamp`。
- 实现必需 hooks:`useIsCurrentUserAdmin()`、`useSubmitRSVP()`、`useGetAllRSVPs()`、`useGetInviteCodes()`、`useGenerateInviteCode()`、`useInternetIdentity()`。
- 支持 URL 参数解析邀请码 `?code=xyz`。
- 支持复制邀请链接到剪贴板。
- 支持根据认证切换管理员/访客视图。
- 支持基本表单验证和错误处理。
- 支持时间戳转换用于显示。
适用边界 · 注意事项
- 未先集成 `extension-authorization`,或缺少 `caffeineai-authorization` / `caffeineai-invite-links` 模块的项目不适用。
- 不是 Caffeine AI / Motoko 项目,或无法使用这些预制模块时,不适用。
- 需要自行修改底层邀请链接/RSVP 状态管理、而不是使用预制模块时不适用。