import { useState } from 'react'; import type { LDClient } from "launchdarkly-js-client-sdk"; import { sendFeedback, type LDFeedbackSentiment } from './sendFeedback'; const ThumbsUpIcon = () => ( ); const ThumbsDownIcon = () => ( ); const HappyFaceIcon = () => ( ); const NeutralFaceIcon = () => ( ); const FrownyFaceIcon = () => ( ); const SpeechBubbleIcon = () => ( ); type SentimentOption = { value: LDFeedbackSentiment; label: string; Icon: React.FC }; const THUMBS_OPTIONS: SentimentOption[] = [ { value: "positive", label: "Thumbs up", Icon: ThumbsUpIcon }, { value: "negative", label: "Thumbs down", Icon: ThumbsDownIcon }, ]; const SMILEY_OPTIONS: SentimentOption[] = [ { value: "positive", label: "Happy face", Icon: HappyFaceIcon }, { value: "neutral", label: "Neutral face", Icon: NeutralFaceIcon }, { value: "negative", label: "Frowny face", Icon: FrownyFaceIcon }, ]; export function PopoverFeedback({ flagKey, prompt, icons, ldClient, }: { flagKey: string; prompt: string; icons: "thumbs" | "smileys" | "none"; ldClient: LDClient; }) { const [isOpen, setIsOpen] = useState(false); const [feedback, setFeedback] = useState(""); const [sentiment, setSentiment] = useState(undefined); const [submitted, setSubmitted] = useState(false); const sentimentOptions = icons === "thumbs" ? THUMBS_OPTIONS : icons === "smileys" ? SMILEY_OPTIONS : []; const handleSubmit = () => { sendFeedback(ldClient, flagKey, feedback, sentiment, prompt); setIsOpen(false); setFeedback(""); setSentiment(undefined); setSubmitted(true); }; if (submitted) { return Thanks for your feedback!; } return ( setIsOpen(!isOpen)} style={{ display: "flex", alignItems: "center", gap: "0.375rem", background: "none", border: "none", cursor: "pointer" }} > Give feedback {isOpen && ( setFeedback(e.target.value)} placeholder={prompt} rows={3} style={{ width: "100%", padding: "0.5rem", marginBottom: "0.5rem", boxSizing: "border-box", border: "1px solid #ccc", borderRadius: "0.25rem", fontFamily: "sans-serif" }} /> {sentimentOptions.length > 0 && ( {sentimentOptions.map(({ value, label, Icon }) => ( setSentiment(sentiment === value ? undefined : value)} aria-label={label} style={{ cursor: "pointer", background: sentiment === value ? "#eee" : "none", border: "none", borderRadius: "0.25rem", padding: "0.25rem 0.5rem" }} > ))} )} Send )} ); } // Usage examples: // // //