Files
template-app/modules/notes/guides/feedback-button.tsx
T

43 lines
1.6 KiB
TypeScript

"use client"
// The notes page's way into the feedback survey (feedback.guide.ts): a button that asks the guides
// module to start `notes.feedback` through the shared surface coordinator (`guides.start`, joint
// contract §12), the same command the support chat's help offers send. It shows only while the guides
// module serves that command, so an app without guides renders nothing here; `kit template:prune
// --without guides` removes it with this folder.
import type { SurfaceCoordinator } from "@conusai-kit/core"
import { useSurfaceCoordinator } from "@conusai-kit/ui"
import { type ReactElement, useState, useSyncExternalStore } from "react"
import type { FeedbackButtonLabels } from "./feedback-labels.js"
const never = () => () => undefined
export function FeedbackButton({ labels }: { labels: FeedbackButtonLabels }): ReactElement | null {
const coordinator = useSurfaceCoordinator<SurfaceCoordinator>()
const served = useSyncExternalStore(
coordinator ? (listener) => coordinator.subscribe(listener) : never,
() => coordinator?.serves("guides.start") ?? false,
() => false,
)
const [unavailable, setUnavailable] = useState(false)
if (!coordinator || !served) return null
const start = async () => {
const result = await coordinator.dispatch({
version: 1,
requestId: globalThis.crypto.randomUUID(),
type: "guides.start",
guideKey: "notes.feedback",
})
setUnavailable(result.status !== "ok")
}
return (
<p>
<button type="button" onClick={() => void start()}>
{labels.open}
</button>{" "}
<span role="status">{unavailable ? labels.unavailable : ""}</span>
</p>
)
}