import { AnimatedElement, Box, IconButton, Portal, Text, Toast, Tooltip, } from "@prismicio/editor-ui"; import { useState } from "react"; import { z } from "zod"; import { telemetry } from "@/apiClient"; import { usePersistedState } from "@/hooks/usePersistedState"; import { getAiFeedbackKey } from "@/utils/localStorageKeys"; export function addAiFeedback({ type, library, sliceId, variationId, langSmithUrl, }: { type: "model"; library: string; sliceId: string; variationId: string; langSmithUrl?: string; }) { const key = getAiFeedbackKey({ type, library, sliceId, variationId }); const feedback = JSON.stringify({ langSmithUrl }); localStorage.setItem(key, feedback); } export function removeAiFeedback({ type, library, sliceId, variationId, }: { type: "model"; library: string; sliceId: string; variationId: string; }) { const key = getAiFeedbackKey({ type, library, sliceId, variationId }); localStorage.removeItem(key); } export function useAiFeedback({ type, library, sliceId, variationId, }: { type: "model"; library: string; sliceId: string; variationId: string; }) { const key = getAiFeedbackKey({ type, library, sliceId, variationId }); const [value, setValue] = usePersistedState(key, undefined, { schema: z.object({ langSmithUrl: z.string().url().optional(), }), }); return { key, value, done: () => setValue(undefined), }; } export function AiFeedback({ type, library, sliceId, variationId, }: { type: "model"; library: string; sliceId: string; variationId: string; }) { const { key, value, done } = useAiFeedback({ type, library, sliceId, variationId, }); const [toastKey, setToastKey] = useState(); const makeSendFeedback = (feedback: "up" | "down") => () => { if (!value) return; setToastKey(key); void telemetry.track({ event: "slice-generation-feedback", type, sliceId, variationId, feedback, langSmithUrl: value.langSmithUrl, }); done(); }; const toastShown = Boolean(toastKey); const onToastOpenChange = (open: boolean) => { if (open) return; setToastKey(undefined); }; return ( <> } icon="check" title={"Thanks for your feedback!"} seconds={2} open={toastShown} onOpenChange={onToastOpenChange} /> {value && ( Did the AI get it right? )} ); }