diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx
index 76dd63b118..e2951b202a 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx
@@ -1,3 +1,5 @@
+import { InboxIcon } from "lucide-react";
+
import { TSurveyQuestionSummaryCta } from "@formbricks/types/surveys";
import { ProgressBar } from "@formbricks/ui/ProgressBar";
@@ -10,12 +12,33 @@ interface CTASummaryProps {
export const CTASummary = ({ questionSummary }: CTASummaryProps) => {
return (
-
-
+
+
+
+
+ {`${questionSummary.impressionCount} Impressions`}
+
+
+
+ {`${questionSummary.clickCount} Clicks`}
+
+ {!questionSummary.question.required && (
+
+
+ {`${questionSummary.skipCount} Skips`}
+
+ )}
+ >
+ }
+ />
-
Click-through rate (CTR)
+
CTR
{convertFloatToNDecimal(questionSummary.ctr.percentage, 1)}%
@@ -23,7 +46,7 @@ export const CTASummary = ({ questionSummary }: CTASummaryProps) => {
- {questionSummary.ctr.count} {questionSummary.ctr.count === 1 ? "click" : "clicks"}
+ {questionSummary.ctr.count} {questionSummary.ctr.count === 1 ? "Click" : "Clicks"}
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx
index 4c974080fe..12316b7b1d 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx
@@ -6,9 +6,11 @@ import { TSurveyQuestionSummary } from "@formbricks/types/surveys";
interface HeadProps {
questionSummary: TSurveyQuestionSummary;
+ showResponses?: boolean;
+ insights?: JSX.Element;
}
-export const QuestionSummaryHeader = ({ questionSummary }: HeadProps) => {
+export const QuestionSummaryHeader = ({ questionSummary, insights, showResponses = true }: HeadProps) => {
const questionType = questionTypes.find((type) => type.id === questionSummary.question.type);
return (
@@ -23,10 +25,13 @@ export const QuestionSummaryHeader = ({ questionSummary }: HeadProps) => {
{questionType &&
}
{questionType ? questionType.label : "Unknown Question Type"} Question
-
-
- {`${questionSummary.responseCount} Responses`}
-
+ {showResponses && (
+
+
+ {`${questionSummary.responseCount} Responses`}
+
+ )}
+ {insights}
{!questionSummary.question.required && (
Optional
)}
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs.tsx
index 76c2c94636..959eb7cb46 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs.tsx
@@ -25,8 +25,8 @@ export const SummaryDropOffs = ({ dropOff }: SummaryDropOffsProps) => {
-
Views
-
Drop Offs
+
Impressions
+
Drop-Offs
{dropOff.map((quesDropOff) => (
{
{quesDropOff.ttc > 0 ? (quesDropOff.ttc / 1000).toFixed(2) + "s" : "N/A"}
-
{quesDropOff.views}
+
{quesDropOff.impressions}
- {quesDropOff.dropOffCount}
+ {quesDropOff.dropOffCount}
({Math.round(quesDropOff.dropOffPercentage)}%)
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryMetadata.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryMetadata.tsx
index 748c661190..31fc0edfc9 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryMetadata.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryMetadata.tsx
@@ -1,8 +1,7 @@
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
import { timeSinceConditionally } from "@formbricks/lib/time";
-import { TSurveySummary } from "@formbricks/types/surveys";
-import { TSurvey } from "@formbricks/types/surveys";
+import { TSurvey, TSurveySummary } from "@formbricks/types/surveys";
import { Button } from "@formbricks/ui/Button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@formbricks/ui/Tooltip";
@@ -71,7 +70,7 @@ export const SummaryMetadata = ({
- : displayCount}
tooltipText="Number of times the survey has been viewed."
@@ -89,7 +88,7 @@ export const SummaryMetadata = ({
tooltipText="Number of times the survey has been completed."
/>
- : dropOffCount}
tooltipText="Number of times the survey has been started but not completed."
@@ -110,7 +109,7 @@ export const SummaryMetadata = ({
className="w-max self-start"
EndIcon={showDropOffs ? ChevronDownIcon : ChevronUpIcon}
onClick={() => setShowDropOffs(!showDropOffs)}>
- Analyze Drop Offs
+ Analyze Drop-Offs
diff --git a/apps/web/playwright/js.spec.ts b/apps/web/playwright/js.spec.ts
index e60c240b61..c85642244e 100644
--- a/apps/web/playwright/js.spec.ts
+++ b/apps/web/playwright/js.spec.ts
@@ -117,13 +117,13 @@ test.describe("JS Package Test", async () => {
// Survey should have 2 Displays
await page.waitForTimeout(1000);
- await expect(page.getByText("Displays2")).toBeVisible();
+ await expect(page.getByText("Impressions2")).toBeVisible();
// Survey should have 1 Response
await page.waitForTimeout(1000);
await expect(page.getByRole("button", { name: "Responses50%" })).toBeVisible();
await expect(page.getByText("1 Responses", { exact: true }).first()).toBeVisible();
- await expect(page.getByText("Click-through rate (CTR)100%")).toBeVisible();
+ await expect(page.getByText("CTR50%")).toBeVisible();
await expect(page.getByText("Somewhat disappointed100%")).toBeVisible();
await expect(page.getByText("Founder100%")).toBeVisible();
await expect(page.getByText("People who believe that PMF").first()).toBeVisible();
diff --git a/packages/lib/response/service.ts b/packages/lib/response/service.ts
index 72ec2d78a2..dc09a917ba 100644
--- a/packages/lib/response/service.ts
+++ b/packages/lib/response/service.ts
@@ -230,7 +230,17 @@ export const createResponse = async (responseInput: TResponseInput): Promise {
@@ -546,7 +546,7 @@ export const getSurveySummaryDropOff = (
if (!currQues.required) {
if (!response.data[currQues.id]) {
- viewsArr[currQuesIdx]++;
+ impressionsArr[currQuesIdx]++;
if (currQuesIdx === survey.questions.length - 1 && !response.finished) {
dropOffArr[currQuesIdx]++;
@@ -577,11 +577,11 @@ export const getSurveySummaryDropOff = (
(currQues.required && !response.data[currQues.id])
) {
dropOffArr[currQuesIdx]++;
- viewsArr[currQuesIdx]++;
+ impressionsArr[currQuesIdx]++;
break;
}
- viewsArr[currQuesIdx]++;
+ impressionsArr[currQuesIdx]++;
let nextQuesIdx = currQuesIdx + 1;
const questionHasCustomLogic = currQues.logic;
@@ -598,7 +598,7 @@ export const getSurveySummaryDropOff = (
if (!response.data[survey.questions[nextQuesIdx]?.id] && !response.finished) {
dropOffArr[nextQuesIdx]++;
- viewsArr[nextQuesIdx]++;
+ impressionsArr[nextQuesIdx]++;
break;
}
@@ -613,20 +613,22 @@ export const getSurveySummaryDropOff = (
});
if (!survey.welcomeCard.enabled) {
- dropOffArr[0] = displayCount - viewsArr[0];
- if (viewsArr[0] > displayCount) dropOffPercentageArr[0] = 0;
+ dropOffArr[0] = displayCount - impressionsArr[0];
+ if (impressionsArr[0] > displayCount) dropOffPercentageArr[0] = 0;
dropOffPercentageArr[0] =
- viewsArr[0] - displayCount >= 0 ? 0 : ((displayCount - viewsArr[0]) / displayCount) * 100 || 0;
+ impressionsArr[0] - displayCount >= 0
+ ? 0
+ : ((displayCount - impressionsArr[0]) / displayCount) * 100 || 0;
- viewsArr[0] = displayCount;
+ impressionsArr[0] = displayCount;
} else {
- dropOffPercentageArr[0] = (dropOffArr[0] / viewsArr[0]) * 100;
+ dropOffPercentageArr[0] = (dropOffArr[0] / impressionsArr[0]) * 100;
}
for (let i = 1; i < survey.questions.length; i++) {
- if (viewsArr[i] !== 0) {
- dropOffPercentageArr[i] = (dropOffArr[i] / viewsArr[i]) * 100;
+ if (impressionsArr[i] !== 0) {
+ dropOffPercentageArr[i] = (dropOffArr[i] / impressionsArr[i]) * 100;
}
}
@@ -635,7 +637,7 @@ export const getSurveySummaryDropOff = (
questionId: question.id,
headline: getLocalizedValue(question.headline, "default"),
ttc: convertFloatTo2Decimal(totalTtc[question.id]) || 0,
- views: viewsArr[index] || 0,
+ impressions: impressionsArr[index] || 0,
dropOffCount: dropOffArr[index] || 0,
dropOffPercentage: convertFloatTo2Decimal(dropOffPercentageArr[index]) || 0,
};
@@ -683,12 +685,13 @@ const checkForI18n = (response: TResponse, id: string, survey: TSurvey, language
export const getQuestionWiseSummary = (
survey: TSurvey,
- responses: TResponse[]
+ responses: TResponse[],
+ dropOff: TSurveySummary["dropOff"]
): TSurveySummary["summary"] => {
const VALUES_LIMIT = 50;
let summary: TSurveySummary["summary"] = [];
- survey.questions.forEach((question) => {
+ survey.questions.forEach((question, idx) => {
switch (question.type) {
case TSurveyQuestionType.OpenText: {
let values: TSurveyQuestionSummaryOpenText["samples"] = [];
@@ -957,15 +960,18 @@ export const getQuestionWiseSummary = (
});
const totalResponses = data.clicked + data.dismissed;
+ const impressions = dropOff[idx].impressions;
summary.push({
type: question.type,
question,
+ impressionCount: impressions,
+ clickCount: data.clicked,
+ skipCount: data.dismissed,
responseCount: totalResponses,
ctr: {
count: data.clicked,
- percentage:
- totalResponses > 0 ? convertFloatTo2Decimal((data.clicked / totalResponses) * 100) : 0,
+ percentage: impressions > 0 ? convertFloatTo2Decimal((data.clicked / impressions) * 100) : 0,
},
});
break;
diff --git a/packages/types/surveys.ts b/packages/types/surveys.ts
index 07d94c7ad1..30f42b5ec1 100644
--- a/packages/types/surveys.ts
+++ b/packages/types/surveys.ts
@@ -679,6 +679,9 @@ export type TSurveyQuestionSummaryNps = z.infer