mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-19 19:21:15 -05:00
feat: adds response count indicator (#2213)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import { getServerSession } from "next-auth";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { getResponses, getSurveySummary } from "@formbricks/lib/response/service";
|
||||
import { getResponseCountBySurveyId, getResponses, getSurveySummary } from "@formbricks/lib/response/service";
|
||||
import { canUserAccessSurvey } from "@formbricks/lib/survey/auth";
|
||||
import { AuthorizationError } from "@formbricks/types/errors";
|
||||
import { TResponse, TResponseFilterCriteria, TSurveySummary } from "@formbricks/types/responses";
|
||||
@@ -58,3 +58,16 @@ export const getSurveySummaryAction = async (
|
||||
|
||||
return await getSurveySummary(surveyId, filterCriteria);
|
||||
};
|
||||
|
||||
export const getResponseCountAction = async (
|
||||
surveyId: string,
|
||||
filters?: TResponseFilterCriteria
|
||||
): Promise<number> => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) throw new AuthorizationError("Not authorized");
|
||||
|
||||
const isAuthorized = await canUserAccessSurvey(session.user.id, surveyId);
|
||||
if (!isAuthorized) throw new AuthorizationError("Not authorized");
|
||||
|
||||
return await getResponseCountBySurveyId(surveyId, filters);
|
||||
};
|
||||
|
||||
@@ -8,9 +8,15 @@ interface SurveyResultsTabProps {
|
||||
activeId: string;
|
||||
environmentId: string;
|
||||
surveyId: string;
|
||||
responseCount: number | null;
|
||||
}
|
||||
|
||||
export default function SurveyResultsTab({ activeId, environmentId, surveyId }: SurveyResultsTabProps) {
|
||||
export default function SurveyResultsTab({
|
||||
activeId,
|
||||
environmentId,
|
||||
surveyId,
|
||||
responseCount,
|
||||
}: SurveyResultsTabProps) {
|
||||
const tabs = [
|
||||
{
|
||||
id: "summary",
|
||||
@@ -20,7 +26,7 @@ export default function SurveyResultsTab({ activeId, environmentId, surveyId }:
|
||||
},
|
||||
{
|
||||
id: "responses",
|
||||
label: "Responses",
|
||||
label: `Responses ${responseCount !== null ? `(${responseCount})` : ""}`,
|
||||
icon: <InboxIcon className="h-5 w-5" />,
|
||||
href: `/environments/${environmentId}/surveys/${surveyId}/responses?referer=true`,
|
||||
},
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { getResponseCountBySurveyId } from "@formbricks/lib/response/service";
|
||||
import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
|
||||
export const getAnalysisData = async (surveyId: string, environmentId: string) => {
|
||||
const [survey, responseCount] = await Promise.all([
|
||||
getSurvey(surveyId),
|
||||
getResponseCountBySurveyId(surveyId),
|
||||
]);
|
||||
if (!survey) throw new Error(`Survey not found: ${surveyId}`);
|
||||
if (survey.environmentId !== environmentId) throw new Error(`Survey not found: ${surveyId}`);
|
||||
|
||||
return { responseCount, survey };
|
||||
};
|
||||
@@ -1,7 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useResponseFilter } from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext";
|
||||
import { getResponsesAction } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import {
|
||||
getResponseCountAction,
|
||||
getResponsesAction,
|
||||
} from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import SurveyResultsTabs from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/components/SurveyResultsTabs";
|
||||
import ResponseTimeline from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTimeline";
|
||||
import CustomFilter from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter";
|
||||
@@ -47,6 +50,7 @@ const ResponsePage = ({
|
||||
responsesPerPage,
|
||||
membershipRole,
|
||||
}: ResponsePageProps) => {
|
||||
const [responseCount, setResponseCount] = useState<number | null>(null);
|
||||
const [responses, setResponses] = useState<TResponse[]>([]);
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const [hasMore, setHasMore] = useState<boolean>(true);
|
||||
@@ -64,23 +68,6 @@ const ResponsePage = ({
|
||||
return checkForRecallInHeadline(survey);
|
||||
}, [survey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams?.get("referer")) {
|
||||
resetState();
|
||||
}
|
||||
}, [searchParams, resetState]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchInitialResponses = async () => {
|
||||
const responses = await getResponsesAction(surveyId, 1, responsesPerPage, filters);
|
||||
if (responses.length < responsesPerPage) {
|
||||
setHasMore(false);
|
||||
}
|
||||
setResponses(responses);
|
||||
};
|
||||
fetchInitialResponses();
|
||||
}, [surveyId, filters, responsesPerPage]);
|
||||
|
||||
const fetchNextPage = useCallback(async () => {
|
||||
const newPage = page + 1;
|
||||
const newResponses = await getResponsesAction(surveyId, newPage, responsesPerPage, filters);
|
||||
@@ -99,9 +86,35 @@ const ResponsePage = ({
|
||||
setResponses(responses.map((response) => (response.id === responseId ? updatedResponse : response)));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams?.get("referer")) {
|
||||
resetState();
|
||||
}
|
||||
}, [searchParams, resetState]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchInitialResponses = async () => {
|
||||
const responses = await getResponsesAction(surveyId, 1, responsesPerPage, filters);
|
||||
if (responses.length < responsesPerPage) {
|
||||
setHasMore(false);
|
||||
}
|
||||
setResponses(responses);
|
||||
};
|
||||
fetchInitialResponses();
|
||||
}, [surveyId, filters, responsesPerPage]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResponsesCount = async () => {
|
||||
const responseCount = await getResponseCountAction(surveyId, filters);
|
||||
setResponseCount(responseCount);
|
||||
};
|
||||
handleResponsesCount();
|
||||
}, [filters, surveyId]);
|
||||
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
setHasMore(true);
|
||||
setResponses([]);
|
||||
}, [filters]);
|
||||
|
||||
return (
|
||||
@@ -119,7 +132,12 @@ const ResponsePage = ({
|
||||
<CustomFilter environmentTags={environmentTags} attributes={attributes} survey={survey} />
|
||||
<ResultsShareButton survey={survey} webAppUrl={webAppUrl} product={product} user={user} />
|
||||
</div>
|
||||
<SurveyResultsTabs activeId="responses" environmentId={environment.id} surveyId={surveyId} />
|
||||
<SurveyResultsTabs
|
||||
activeId="responses"
|
||||
environmentId={environment.id}
|
||||
surveyId={surveyId}
|
||||
responseCount={responseCount}
|
||||
/>
|
||||
<ResponseTimeline
|
||||
environment={environment}
|
||||
surveyId={surveyId}
|
||||
|
||||
@@ -20,7 +20,7 @@ import RatingSummary from "./RatingSummary";
|
||||
|
||||
interface SummaryListProps {
|
||||
summary: TSurveySummary["summary"];
|
||||
responseCount: number;
|
||||
responseCount: number | null;
|
||||
environment: TEnvironment;
|
||||
survey: TSurvey;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export default function SummaryList({ summary, environment, responseCount, surve
|
||||
<div className="mt-10 space-y-8">
|
||||
{survey.type === "web" && responseCount === 0 && !environment.widgetSetupCompleted ? (
|
||||
<EmptyInAppSurveys environment={environment} />
|
||||
) : responseCount === 0 ? (
|
||||
) : !responseCount ? (
|
||||
<EmptySpaceFiller
|
||||
type="response"
|
||||
environment={environment}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useResponseFilter } from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext";
|
||||
import { getSurveySummaryAction } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import {
|
||||
getResponseCountAction,
|
||||
getSurveySummaryAction,
|
||||
} from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import SurveyResultsTabs from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/components/SurveyResultsTabs";
|
||||
import SummaryDropOffs from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs";
|
||||
import SummaryList from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryList";
|
||||
@@ -24,6 +27,21 @@ import ContentWrapper from "@formbricks/ui/ContentWrapper";
|
||||
|
||||
import ResultsShareButton from "../../../components/ResultsShareButton";
|
||||
|
||||
const initialSurveySummary: TSurveySummary = {
|
||||
meta: {
|
||||
completedPercentage: 0,
|
||||
completedResponses: 0,
|
||||
displayCount: 0,
|
||||
dropOffPercentage: 0,
|
||||
dropOffCount: 0,
|
||||
startsPercentage: 0,
|
||||
totalResponses: 0,
|
||||
ttcAverage: 0,
|
||||
},
|
||||
dropOff: [],
|
||||
summary: [],
|
||||
};
|
||||
|
||||
interface SummaryPageProps {
|
||||
environment: TEnvironment;
|
||||
survey: TSurvey;
|
||||
@@ -34,7 +52,6 @@ interface SummaryPageProps {
|
||||
environmentTags: TTag[];
|
||||
attributes: TSurveyPersonAttributes;
|
||||
membershipRole?: TMembershipRole;
|
||||
responseCount: number;
|
||||
}
|
||||
|
||||
const SummaryPage = ({
|
||||
@@ -47,23 +64,10 @@ const SummaryPage = ({
|
||||
environmentTags,
|
||||
attributes,
|
||||
membershipRole,
|
||||
responseCount,
|
||||
}: SummaryPageProps) => {
|
||||
const [responseCount, setResponseCount] = useState<number | null>(null);
|
||||
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
||||
const [surveySummary, setSurveySummary] = useState<TSurveySummary>({
|
||||
meta: {
|
||||
completedPercentage: 0,
|
||||
completedResponses: 0,
|
||||
displayCount: 0,
|
||||
dropOffPercentage: 0,
|
||||
dropOffCount: 0,
|
||||
startsPercentage: 0,
|
||||
totalResponses: 0,
|
||||
ttcAverage: 0,
|
||||
},
|
||||
dropOff: [],
|
||||
summary: [],
|
||||
});
|
||||
const [surveySummary, setSurveySummary] = useState<TSurveySummary>(initialSurveySummary);
|
||||
const [showDropOffs, setShowDropOffs] = useState<boolean>(false);
|
||||
|
||||
const filters = useMemo(
|
||||
@@ -72,11 +76,18 @@ const SummaryPage = ({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSurveySummary = async () => {
|
||||
const handleInitialData = async () => {
|
||||
const responseCount = await getResponseCountAction(surveyId, filters);
|
||||
setResponseCount(responseCount);
|
||||
if (responseCount === 0) {
|
||||
setSurveySummary(initialSurveySummary);
|
||||
return;
|
||||
}
|
||||
const response = await getSurveySummaryAction(surveyId, filters);
|
||||
setSurveySummary(response);
|
||||
};
|
||||
fetchSurveySummary();
|
||||
|
||||
handleInitialData();
|
||||
}, [filters, surveyId]);
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
@@ -105,7 +116,12 @@ const SummaryPage = ({
|
||||
<CustomFilter environmentTags={environmentTags} attributes={attributes} survey={survey} />
|
||||
<ResultsShareButton survey={survey} webAppUrl={webAppUrl} product={product} user={user} />
|
||||
</div>
|
||||
<SurveyResultsTabs activeId="summary" environmentId={environment.id} surveyId={surveyId} />
|
||||
<SurveyResultsTabs
|
||||
activeId="summary"
|
||||
environmentId={environment.id}
|
||||
surveyId={surveyId}
|
||||
responseCount={responseCount}
|
||||
/>
|
||||
<SummaryMetadata
|
||||
survey={survey}
|
||||
surveySummary={surveySummary.meta}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getAnalysisData } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/data";
|
||||
import SummaryPage from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
@@ -8,6 +8,7 @@ import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
import { getResponsePersonAttributes } from "@formbricks/lib/response/service";
|
||||
import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
import { getTagsByEnvironmentId } from "@formbricks/lib/tag/service";
|
||||
import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
|
||||
import { getUser } from "@formbricks/lib/user/service";
|
||||
@@ -18,10 +19,19 @@ export default async function Page({ params }) {
|
||||
throw new Error("Unauthorized");
|
||||
}
|
||||
|
||||
const [{ survey, responseCount }, environment] = await Promise.all([
|
||||
getAnalysisData(params.surveyId, params.environmentId),
|
||||
getEnvironment(params.environmentId),
|
||||
]);
|
||||
const surveyId = params.surveyId;
|
||||
|
||||
if (!surveyId) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
const survey = await getSurvey(surveyId);
|
||||
|
||||
if (!survey) {
|
||||
throw new Error("Survey not found");
|
||||
}
|
||||
const environment = await getEnvironment(survey.environmentId);
|
||||
|
||||
if (!environment) {
|
||||
throw new Error("Environment not found");
|
||||
}
|
||||
@@ -59,7 +69,6 @@ export default async function Page({ params }) {
|
||||
environmentTags={tags}
|
||||
attributes={attributes}
|
||||
membershipRole={currentUserMembership?.role}
|
||||
responseCount={responseCount}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ interface SurveyResultsTabProps {
|
||||
activeId: string;
|
||||
environmentId: string;
|
||||
surveyId: string;
|
||||
responseCount: number | null;
|
||||
sharingKey: string;
|
||||
}
|
||||
|
||||
@@ -15,6 +16,7 @@ export default function SurveyResultsTab({
|
||||
activeId,
|
||||
environmentId,
|
||||
surveyId,
|
||||
responseCount,
|
||||
sharingKey,
|
||||
}: SurveyResultsTabProps) {
|
||||
const tabs = [
|
||||
@@ -26,7 +28,7 @@ export default function SurveyResultsTab({
|
||||
},
|
||||
{
|
||||
id: "responses",
|
||||
label: "Responses",
|
||||
label: `Responses ${responseCount !== null ? `(${responseCount})` : ""}`,
|
||||
icon: <InboxIcon className="h-5 w-5" />,
|
||||
href: `/share/${sharingKey}/responses?referer=true`,
|
||||
},
|
||||
|
||||
@@ -4,7 +4,10 @@ import { useResponseFilter } from "@/app/(app)/environments/[environmentId]/comp
|
||||
import { getFormattedFilters } from "@/app/lib/surveys/surveys";
|
||||
import SurveyResultsTabs from "@/app/share/[sharingKey]/(analysis)/components/SurveyResultsTabs";
|
||||
import ResponseTimeline from "@/app/share/[sharingKey]/(analysis)/responses/components/ResponseTimeline";
|
||||
import { getResponsesBySurveySharingKeyAction } from "@/app/share/[sharingKey]/action";
|
||||
import {
|
||||
getResponseCountBySurveySharingKeyAction,
|
||||
getResponsesBySurveySharingKeyAction,
|
||||
} from "@/app/share/[sharingKey]/action";
|
||||
import CustomFilter from "@/app/share/[sharingKey]/components/CustomFilter";
|
||||
import SummaryHeader from "@/app/share/[sharingKey]/components/SummaryHeader";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
@@ -43,6 +46,7 @@ const ResponsePage = ({
|
||||
const [responses, setResponses] = useState<TResponse[]>([]);
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const [hasMore, setHasMore] = useState<boolean>(true);
|
||||
const [responseCount, setResponseCount] = useState<number | null>(null);
|
||||
|
||||
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
||||
|
||||
@@ -57,6 +61,21 @@ const ResponsePage = ({
|
||||
return checkForRecallInHeadline(survey);
|
||||
}, [survey]);
|
||||
|
||||
const fetchNextPage = useCallback(async () => {
|
||||
const newPage = page + 1;
|
||||
const newResponses = await getResponsesBySurveySharingKeyAction(
|
||||
sharingKey,
|
||||
newPage,
|
||||
responsesPerPage,
|
||||
filters
|
||||
);
|
||||
if (newResponses.length === 0 || newResponses.length < responsesPerPage) {
|
||||
setHasMore(false);
|
||||
}
|
||||
setResponses([...responses, ...newResponses]);
|
||||
setPage(newPage);
|
||||
}, [filters, page, responses, responsesPerPage, sharingKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams?.get("referer")) {
|
||||
resetState();
|
||||
@@ -74,20 +93,13 @@ const ResponsePage = ({
|
||||
fetchInitialResponses();
|
||||
}, [filters, responsesPerPage, sharingKey]);
|
||||
|
||||
const fetchNextPage = useCallback(async () => {
|
||||
const newPage = page + 1;
|
||||
const newResponses = await getResponsesBySurveySharingKeyAction(
|
||||
sharingKey,
|
||||
newPage,
|
||||
responsesPerPage,
|
||||
filters
|
||||
);
|
||||
if (newResponses.length === 0 || newResponses.length < responsesPerPage) {
|
||||
setHasMore(false);
|
||||
}
|
||||
setResponses([...responses, ...newResponses]);
|
||||
setPage(newPage);
|
||||
}, [filters, page, responses, responsesPerPage, sharingKey]);
|
||||
useEffect(() => {
|
||||
const handleResponsesCount = async () => {
|
||||
const responseCount = await getResponseCountBySurveySharingKeyAction(sharingKey, filters);
|
||||
setResponseCount(responseCount);
|
||||
};
|
||||
handleResponsesCount();
|
||||
}, [filters, sharingKey]);
|
||||
|
||||
return (
|
||||
<ContentWrapper>
|
||||
@@ -97,6 +109,7 @@ const ResponsePage = ({
|
||||
activeId="responses"
|
||||
environmentId={environment.id}
|
||||
surveyId={surveyId}
|
||||
responseCount={responseCount}
|
||||
sharingKey={sharingKey}
|
||||
/>
|
||||
<ResponseTimeline
|
||||
|
||||
@@ -6,7 +6,10 @@ import SummaryList from "@/app/(app)/environments/[environmentId]/surveys/[surve
|
||||
import SummaryMetadata from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryMetadata";
|
||||
import { getFormattedFilters } from "@/app/lib/surveys/surveys";
|
||||
import SurveyResultsTabs from "@/app/share/[sharingKey]/(analysis)/components/SurveyResultsTabs";
|
||||
import { getSummaryBySurveySharingKeyAction } from "@/app/share/[sharingKey]/action";
|
||||
import {
|
||||
getResponseCountBySurveySharingKeyAction,
|
||||
getSummaryBySurveySharingKeyAction,
|
||||
} from "@/app/share/[sharingKey]/action";
|
||||
import CustomFilter from "@/app/share/[sharingKey]/components/CustomFilter";
|
||||
import SummaryHeader from "@/app/share/[sharingKey]/components/SummaryHeader";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
@@ -20,6 +23,21 @@ import { TSurvey } from "@formbricks/types/surveys";
|
||||
import { TTag } from "@formbricks/types/tags";
|
||||
import ContentWrapper from "@formbricks/ui/ContentWrapper";
|
||||
|
||||
const initialSurveySummary: TSurveySummary = {
|
||||
meta: {
|
||||
completedPercentage: 0,
|
||||
completedResponses: 0,
|
||||
displayCount: 0,
|
||||
dropOffPercentage: 0,
|
||||
dropOffCount: 0,
|
||||
startsPercentage: 0,
|
||||
totalResponses: 0,
|
||||
ttcAverage: 0,
|
||||
},
|
||||
dropOff: [],
|
||||
summary: [],
|
||||
};
|
||||
|
||||
interface SummaryPageProps {
|
||||
environment: TEnvironment;
|
||||
survey: TSurvey;
|
||||
@@ -28,7 +46,6 @@ interface SummaryPageProps {
|
||||
sharingKey: string;
|
||||
environmentTags: TTag[];
|
||||
attributes: TSurveyPersonAttributes;
|
||||
responseCount: number;
|
||||
}
|
||||
|
||||
const SummaryPage = ({
|
||||
@@ -39,23 +56,11 @@ const SummaryPage = ({
|
||||
sharingKey,
|
||||
environmentTags,
|
||||
attributes,
|
||||
responseCount,
|
||||
}: SummaryPageProps) => {
|
||||
const [responseCount, setResponseCount] = useState<number | null>(null);
|
||||
|
||||
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
||||
const [surveySummary, setSurveySummary] = useState<TSurveySummary>({
|
||||
meta: {
|
||||
completedPercentage: 0,
|
||||
completedResponses: 0,
|
||||
displayCount: 0,
|
||||
dropOffPercentage: 0,
|
||||
dropOffCount: 0,
|
||||
startsPercentage: 0,
|
||||
totalResponses: 0,
|
||||
ttcAverage: 0,
|
||||
},
|
||||
dropOff: [],
|
||||
summary: [],
|
||||
});
|
||||
const [surveySummary, setSurveySummary] = useState<TSurveySummary>(initialSurveySummary);
|
||||
const [showDropOffs, setShowDropOffs] = useState<boolean>(false);
|
||||
|
||||
const filters = useMemo(
|
||||
@@ -64,11 +69,18 @@ const SummaryPage = ({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSurveySummary = async () => {
|
||||
const handleInitialData = async () => {
|
||||
const responseCount = await getResponseCountBySurveySharingKeyAction(sharingKey, filters);
|
||||
setResponseCount(responseCount);
|
||||
if (responseCount === 0) {
|
||||
setSurveySummary(initialSurveySummary);
|
||||
return;
|
||||
}
|
||||
const response = await getSummaryBySurveySharingKeyAction(sharingKey, filters);
|
||||
setSurveySummary(response);
|
||||
};
|
||||
fetchSurveySummary();
|
||||
|
||||
handleInitialData();
|
||||
}, [filters, sharingKey]);
|
||||
|
||||
survey = useMemo(() => {
|
||||
@@ -91,6 +103,7 @@ const SummaryPage = ({
|
||||
activeId="summary"
|
||||
environmentId={environment.id}
|
||||
surveyId={surveyId}
|
||||
responseCount={responseCount}
|
||||
sharingKey={sharingKey}
|
||||
/>
|
||||
<SummaryMetadata
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getAnalysisData } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/data";
|
||||
import SummaryPage from "@/app/share/[sharingKey]/(analysis)/summary/components/SummaryPage";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
@@ -23,10 +22,7 @@ export default async function Page({ params }) {
|
||||
if (!survey) {
|
||||
throw new Error("Survey not found");
|
||||
}
|
||||
const [{ responseCount }, environment] = await Promise.all([
|
||||
getAnalysisData(survey.id, survey.environmentId),
|
||||
getEnvironment(survey.environmentId),
|
||||
]);
|
||||
const environment = await getEnvironment(survey.environmentId);
|
||||
|
||||
if (!environment) {
|
||||
throw new Error("Environment not found");
|
||||
@@ -50,7 +46,6 @@ export default async function Page({ params }) {
|
||||
product={product}
|
||||
environmentTags={tags}
|
||||
attributes={attributes}
|
||||
responseCount={responseCount}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use server";
|
||||
|
||||
import { getResponses, getSurveySummary } from "@formbricks/lib/response/service";
|
||||
import { getResponseCountBySurveyId, getResponses, getSurveySummary } from "@formbricks/lib/response/service";
|
||||
import { getSurveyIdByResultShareKey } from "@formbricks/lib/survey/service";
|
||||
import { AuthorizationError } from "@formbricks/types/errors";
|
||||
import { TResponse, TResponseFilterCriteria, TSurveySummary } from "@formbricks/types/responses";
|
||||
@@ -28,3 +28,13 @@ export const getSummaryBySurveySharingKeyAction = async (
|
||||
|
||||
return await getSurveySummary(surveyId, filterCriteria);
|
||||
};
|
||||
|
||||
export const getResponseCountBySurveySharingKeyAction = async (
|
||||
sharingKey: string,
|
||||
filterCriteria?: TResponseFilterCriteria
|
||||
): Promise<number> => {
|
||||
const surveyId = await getSurveyIdByResultShareKey(sharingKey);
|
||||
if (!surveyId) throw new AuthorizationError("Not authorized");
|
||||
|
||||
return await getResponseCountBySurveyId(surveyId, filterCriteria);
|
||||
};
|
||||
|
||||
@@ -308,10 +308,10 @@ export const buildWhereClause = (filterCriteria?: TResponseFilterCriteria) => {
|
||||
};
|
||||
|
||||
export const getResponsesFileName = (surveyName: string, extension: string) => {
|
||||
surveyName = sanitizeString(surveyName);
|
||||
const sanitizedSurveyName = sanitizeString(surveyName);
|
||||
|
||||
const formattedDateString = getTodaysDateTimeFormatted("-");
|
||||
return `export-${surveyName.split(" ").join("-")}-${formattedDateString}.${extension}`.toLocaleLowerCase();
|
||||
return `export-${sanitizedSurveyName.split(" ").join("-")}-${formattedDateString}.${extension}`.toLocaleLowerCase();
|
||||
};
|
||||
|
||||
export const extracMetadataKeys = (obj: TResponse["meta"]) => {
|
||||
|
||||
Reference in New Issue
Block a user