feat: adds feedback component

This commit is contained in:
Piyush Gupta
2024-10-03 17:16:06 +05:30
parent 5e17b7919f
commit dc894bae2a
5 changed files with 82 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
import { UserIcon } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import formbricks from "@formbricks/js/app";
import { getPersonIdentifier } from "@formbricks/lib/person/utils";
import { timeSince } from "@formbricks/lib/time";
import { TAttributeClass } from "@formbricks/types/attribute-classes";
@@ -28,6 +29,8 @@ interface OpenTextSummaryProps {
survey: TSurvey;
attributeClasses: TAttributeClass[];
isAiEnabled: boolean;
productId: string;
productName: string;
}
export const OpenTextSummary = ({
@@ -36,6 +39,8 @@ export const OpenTextSummary = ({
survey,
attributeClasses,
isAiEnabled,
productId,
productName,
}: OpenTextSummaryProps) => {
const [visibleResponses, setVisibleResponses] = useState(10);
const [activeTab, setActiveTab] = useState<"insights" | "responses">(
@@ -65,6 +70,22 @@ export const OpenTextSummary = ({
},
];
const handleFeedback = (feedback: "positive" | "negative") => {
formbricks.track("Insight Feedback", {
hiddenFields: {
feedbackSentiment: feedback,
productId,
productName,
surveyId: survey.id,
surveyName: survey.name,
insightId: currentInsight?.id,
insightCategory: currentInsight?.category,
questionId: questionSummary.question.id,
environmentId,
},
});
};
return (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader
@@ -78,6 +99,7 @@ export const OpenTextSummary = ({
insight={currentInsight}
surveyId={survey.id}
questionId={questionSummary.question.id}
handleFeedback={handleFeedback}
/>
{isAiEnabled && (
<div className="flex items-center justify-between pr-4">

View File

@@ -40,6 +40,7 @@ interface SummaryListProps {
totalResponseCount: number;
attributeClasses: TAttributeClass[];
isAiEnabled: boolean;
productName: string;
}
export const SummaryList = ({
@@ -50,6 +51,7 @@ export const SummaryList = ({
totalResponseCount,
attributeClasses,
isAiEnabled,
productName,
}: SummaryListProps) => {
const { setSelectedFilter, selectedFilter } = useResponseFilter();
const widgetSetupCompleted =
@@ -134,6 +136,8 @@ export const SummaryList = ({
survey={survey}
attributeClasses={attributeClasses}
isAiEnabled={isAiEnabled}
productId={environment.productId}
productName={productName}
/>
);
}

View File

@@ -48,6 +48,7 @@ interface SummaryPageProps {
totalResponseCount: number;
attributeClasses: TAttributeClass[];
isAiEnabled: boolean;
productName: string;
}
export const SummaryPage = ({
@@ -58,6 +59,7 @@ export const SummaryPage = ({
totalResponseCount,
attributeClasses,
isAiEnabled,
productName,
}: SummaryPageProps) => {
const params = useParams();
const sharingKey = params.sharingKey as string;
@@ -177,6 +179,7 @@ export const SummaryPage = ({
totalResponseCount={totalResponseCount}
attributeClasses={attributeClasses}
isAiEnabled={isAiEnabled}
productName={productName}
/>
</>
);

View File

@@ -100,6 +100,7 @@ const Page = async ({ params }) => {
totalResponseCount={totalResponseCount}
attributeClasses={attributeClasses}
isAiEnabled={isAiEnabled}
productName={product.name}
/>
</PageContentWrapper>
);

View File

@@ -1,5 +1,6 @@
"use client";
import { ThumbsDownIcon, ThumbsUpIcon } from "lucide-react";
import { useEffect, useState } from "react";
import Markdown from "react-markdown";
import { getFormattedErrorMessage } from "@formbricks/lib/actionClient/helper";
@@ -8,7 +9,7 @@ import { TDocument } from "@formbricks/types/documents";
import { TInsight } from "@formbricks/types/insights";
import { Badge } from "../Badge";
import { Card, CardContent, CardFooter } from "../Card";
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "../Sheet";
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle } from "../Sheet";
import { getDocumentsByInsightIdSurveyIdQuestionIdAction } from "./actions";
interface InsightSheetProps {
@@ -17,9 +18,17 @@ interface InsightSheetProps {
insight: TInsight | null;
surveyId: string;
questionId: string;
handleFeedback: (feedback: "positive" | "negative") => void;
}
export const InsightSheet = ({ isOpen, setIsOpen, insight, surveyId, questionId }: InsightSheetProps) => {
export const InsightSheet = ({
isOpen,
setIsOpen,
insight,
surveyId,
questionId,
handleFeedback,
}: InsightSheetProps) => {
const [documents, setDocuments] = useState<TDocument[]>([]);
useEffect(() => {
@@ -49,22 +58,31 @@ export const InsightSheet = ({ isOpen, setIsOpen, insight, surveyId, questionId
if (!insight) {
return null;
}
const handleFeedbackClick = (feedback: "positive" | "negative") => {
setIsOpen(false);
handleFeedback(feedback);
};
return (
<Sheet open={isOpen} onOpenChange={(v) => setIsOpen(v)}>
<SheetContent className="w-[400rem] bg-white lg:max-w-lg xl:max-w-2xl">
<SheetHeader>
<SheetTitle>
<span className="mr-3">{insight.title}</span>
{insight.category === "complaint" ? (
<Badge text="Complaint" type="error" size="tiny" />
) : insight.category === "featureRequest" ? (
<Badge text="Request" type="warning" size="tiny" />
) : insight.category === "praise" ? (
<Badge text="Praise" type="success" size="tiny" />
) : null}
</SheetTitle>
<SheetDescription>{insight.description}</SheetDescription>
<div className="flex flex-col space-y-2 pt-4">
<>
<Sheet open={isOpen} onOpenChange={(v) => setIsOpen(v)}>
<SheetContent className="flex h-full w-[400rem] flex-col bg-white lg:max-w-lg xl:max-w-2xl">
<SheetHeader>
<SheetTitle>
<span className="mr-3">{insight.title}</span>
{insight.category === "complaint" ? (
<Badge text="Complaint" type="error" size="tiny" />
) : insight.category === "featureRequest" ? (
<Badge text="Request" type="warning" size="tiny" />
) : insight.category === "praise" ? (
<Badge text="Praise" type="success" size="tiny" />
) : null}
</SheetTitle>
<SheetDescription>{insight.description}</SheetDescription>
</SheetHeader>
<div className="flex flex-1 flex-col space-y-2 overflow-auto pt-4">
{documents.map((document) => (
<Card>
<CardContent className="p-4 text-sm">
@@ -86,8 +104,22 @@ export const InsightSheet = ({ isOpen, setIsOpen, insight, surveyId, questionId
</Card>
))}
</div>
</SheetHeader>
</SheetContent>
</Sheet>
<SheetFooter>
<div className="flex items-center gap-2">
<p>Did you find this insight helpful?</p>
<ThumbsUpIcon
className="upvote h-5 w-5 cursor-pointer"
onClick={() => handleFeedbackClick("positive")}
/>
<ThumbsDownIcon
className="downvote h-5 w-5 cursor-pointer"
onClick={() => handleFeedbackClick("negative")}
/>
</div>
</SheetFooter>
</SheetContent>
</Sheet>
</>
);
};