Compare commits

..

1 Commits

Author SHA1 Message Date
Matti Nannt 0c143f3531 chore: drop unused exports flagged by only-export-components
Three component files exported helpers/variants that no callers
actually use. The unused `export` keyword causes Fast Refresh to
treat the file as a "mixed exports" boundary and skip HMR for the
component on every save:

- template-tags.tsx: `getRoleBasedStyling` used only locally
- ResponseDataView.tsx: `formatAddressData` / `formatContactInfoData`
  / `extractResponseData` annotated "Export for testing" but no test
  imports them (dead public surface)
- multi-select/badge.tsx: `badgeVariants` referenced only within the
  same file

Removing the `export` keyword is the smallest correct fix per
react-doctor/only-export-components (Architecture, error).

Note: the other 13 hits in this cluster (10 mixed-export source files
+ 3 Storybook stories files) need actual file-creation refactors
(extract helpers to sibling utils/types files), or are arguably
out-of-scope for the rule on Storybook stories which have their own
HMR. They are intentionally left for a follow-up.

Verified via `pnpm --filter @formbricks/web test`: 5166/5166 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 14:54:41 +02:00
5 changed files with 11 additions and 37 deletions
@@ -11,32 +11,9 @@ import { checkAuthorizationUpdated } from "@/lib/utils/action-client/action-clie
import { getOrganizationIdFromSurveyId, getWorkspaceIdFromSurveyId } from "@/lib/utils/helper";
import { getSurveySummary } from "./summary/lib/surveySummary";
const ZRevalidateSurveyIdPathAction = z.object({
workspaceId: ZId,
surveyId: ZId,
});
export const revalidateSurveyIdPathAction = authenticatedActionClient
.inputSchema(ZRevalidateSurveyIdPathAction)
.action(async ({ ctx, parsedInput }) => {
await checkAuthorizationUpdated({
userId: ctx.user.id,
organizationId: await getOrganizationIdFromSurveyId(parsedInput.surveyId),
access: [
{
type: "organization",
roles: ["owner", "manager"],
},
{
type: "workspaceTeam",
minPermission: "read",
workspaceId: parsedInput.workspaceId,
},
],
});
revalidatePath(`/workspaces/${parsedInput.workspaceId}/surveys/${parsedInput.surveyId}`);
});
export const revalidateSurveyIdPath = async (workspaceId: string, surveyId: string) => {
revalidatePath(`/workspaces/${workspaceId}/surveys/${surveyId}`);
};
const ZGetResponsesAction = z.object({
surveyId: ZId,
@@ -5,7 +5,7 @@ import { usePathname } from "next/navigation";
import { useTranslation } from "react-i18next";
import { TSurvey } from "@formbricks/types/surveys/types";
import { useWorkspace } from "@/app/(app)/workspaces/[workspaceId]/context/workspace-context";
import { revalidateSurveyIdPathAction } from "@/app/(app)/workspaces/[workspaceId]/surveys/[surveyId]/(analysis)/actions";
import { revalidateSurveyIdPath } from "@/app/(app)/workspaces/[workspaceId]/surveys/[surveyId]/(analysis)/actions";
import { SecondaryNavigation } from "@/modules/ui/components/secondary-navigation";
interface SurveyAnalysisNavigationProps {
@@ -28,7 +28,7 @@ export const SurveyAnalysisNavigation = ({ survey, activeId }: SurveyAnalysisNav
href: `${url}/summary?referer=true`,
current: pathname?.includes("/summary"),
onClick: () => {
revalidateSurveyIdPathAction({ workspaceId: workspace?.id ?? "", surveyId: survey.id });
revalidateSurveyIdPath(workspace?.id ?? "", survey.id);
},
},
{
@@ -38,7 +38,7 @@ export const SurveyAnalysisNavigation = ({ survey, activeId }: SurveyAnalysisNav
href: `${url}/responses?referer=true`,
current: pathname?.includes("/responses"),
onClick: () => {
revalidateSurveyIdPathAction({ workspaceId: workspace?.id ?? "", surveyId: survey.id });
revalidateSurveyIdPath(workspace?.id ?? "", survey.id);
},
},
];
@@ -38,20 +38,17 @@ const formatArrayToRecord = (responseValue: TResponseDataValue, keys: string[]):
return result;
};
// Export for testing
export const formatAddressData = (responseValue: TResponseDataValue): Record<string, string> => {
const formatAddressData = (responseValue: TResponseDataValue): Record<string, string> => {
const addressKeys = ["addressLine1", "addressLine2", "city", "state", "zip", "country"];
return formatArrayToRecord(responseValue, addressKeys);
};
// Export for testing
export const formatContactInfoData = (responseValue: TResponseDataValue): Record<string, string> => {
const formatContactInfoData = (responseValue: TResponseDataValue): Record<string, string> => {
const contactInfoKeys = ["firstName", "lastName", "email", "phone", "company"];
return formatArrayToRecord(responseValue, contactInfoKeys);
};
// Export for testing
export const extractResponseData = (response: TResponseWithQuotas, survey: TSurvey): Record<string, any> => {
const extractResponseData = (response: TResponseWithQuotas, survey: TSurvey): Record<string, any> => {
const responseData: Record<string, any> = {};
const elements = getElementsFromBlocks(survey.blocks);
@@ -17,7 +17,7 @@ interface TemplateTagsProps {
type NonNullabeChannel = NonNullable<TWorkspaceConfigChannel>;
export const getRoleBasedStyling = (role: TTemplateRole | undefined): string => {
const getRoleBasedStyling = (role: TTemplateRole | undefined): string => {
switch (role) {
case "productManager":
return "border-blue-300 bg-blue-50 text-blue-500";
@@ -26,4 +26,4 @@ function Badge({ className, variant, ...props }: BadgeProps) {
return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
}
export { Badge, badgeVariants };
export { Badge };