chore: Replace default exports/imports with module exports (#2617)

This commit is contained in:
Piyush Gupta
2024-05-14 19:47:49 +05:30
committed by GitHub
parent d2b27b046b
commit 11888f3e38
585 changed files with 2408 additions and 2179 deletions
+3 -3
View File
@@ -1,12 +1,12 @@
import { Result, err, ok, wrapThrows } from "@formbricks/types/errorHandlers";
import { NetworkError } from "@formbricks/types/errors";
export async function makeRequest<T>(
export const makeRequest = async <T>(
apiHost: string,
endpoint: string,
method: "GET" | "POST" | "PUT" | "DELETE",
data?: any
): Promise<Result<T, NetworkError | Error>> {
): Promise<Result<T, NetworkError | Error>> => {
const url = new URL(endpoint, apiHost);
const body = JSON.stringify(data);
@@ -33,4 +33,4 @@ export async function makeRequest<T>(
}
return ok(json.data as T);
}
};
@@ -10,7 +10,7 @@ import {
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(async (tx) => {
const allSurveysWithAttributeFilters = await prisma.survey.findMany({
where: {
@@ -101,7 +101,7 @@ async function main() {
// delete all attribute filters
await tx.surveyAttributeFilter.deleteMany({});
});
}
};
main()
.catch(async (e) => {
@@ -5,7 +5,7 @@ import { hasStringSubheaders, translateSurvey } from "./lib/i18n";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
// Translate Surveys
@@ -39,7 +39,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch(async (e) => {
@@ -3,7 +3,7 @@ import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
const surveys = await tx.survey.findMany({
@@ -47,7 +47,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch(async (e) => {
@@ -4,7 +4,7 @@ import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
const surveys = await tx.survey.findMany({
@@ -41,7 +41,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch(async (e) => {
@@ -5,7 +5,7 @@ import { translateSurvey } from "./lib/i18n";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
// Translate Surveys
@@ -92,7 +92,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch(async (e) => {
@@ -7,7 +7,7 @@ const DEFAULT_STYLING = {
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
// product table with brand color and the highlight border color (if available)
@@ -131,7 +131,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch(async (e) => {
console.error(e);
@@ -2,7 +2,7 @@ import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
// get all the persons that have an attribute class with the name "userId"
@@ -49,7 +49,7 @@ async function main() {
timeout: 60000 * 3, // 3 minutes
}
);
}
};
main()
.catch(async (e) => {
console.error(e);
@@ -2,7 +2,7 @@ import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
// Retrieve all surveys of type "web" with necessary fields for efficient processing
@@ -132,7 +132,7 @@ async function main() {
timeout: 50000,
}
);
}
};
main()
.catch((e: Error) => {
@@ -4,7 +4,7 @@ import { Prisma, PrismaClient } from "@prisma/client";
const createId = init({ length: 5 });
const prisma = new PrismaClient();
async function main() {
const main = async () => {
await prisma.$transaction(
async (tx) => {
const startTime = Date.now();
@@ -193,7 +193,7 @@ async function main() {
timeout: 180000, // 3 minutes
}
);
}
};
main()
.catch((e: Error) => {
@@ -18,7 +18,7 @@ import {
} from "@formbricks/ui/DropdownMenu";
import { transferOwnershipAction, updateInviteAction, updateMembershipAction } from "../lib/actions";
import TransferOwnershipModal from "./TransferOwnershipModal";
import { TransferOwnershipModal } from "./TransferOwnershipModal";
interface Role {
isAdminOrOwner: boolean;
@@ -2,7 +2,7 @@
import { Dispatch, SetStateAction, useState } from "react";
import CustomDialog from "@formbricks/ui/CustomDialog";
import { CustomDialog } from "@formbricks/ui/CustomDialog";
import { Input } from "@formbricks/ui/Input";
interface TransferOwnershipModalProps {
@@ -13,13 +13,13 @@ interface TransferOwnershipModalProps {
isLoading?: boolean;
}
export default function TransferOwnershipModal({
export const TransferOwnershipModal = ({
setOpen,
open,
memberName,
onSubmit,
isLoading,
}: TransferOwnershipModalProps) {
}: TransferOwnershipModalProps) => {
const [inputValue, setInputValue] = useState("");
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -61,4 +61,4 @@ export default function TransferOwnershipModal({
</div>
</CustomDialog>
);
}
};
@@ -218,7 +218,7 @@ const AttributeTabContent = ({ attributeClasses, onAddFilter, setOpen }: Attribu
);
};
const AddFilterModal = ({
export const AddFilterModal = ({
onAddFilter,
open,
setOpen,
@@ -558,5 +558,3 @@ const AddFilterModal = ({
</Modal>
);
};
export default AddFilterModal;
@@ -15,10 +15,10 @@ import { TBaseFilter, TSegment, TSegmentCreateInput, TSegmentUpdateInput } from
import { TSurvey } from "@formbricks/types/surveys";
import { AlertDialog } from "@formbricks/ui/AlertDialog";
import { Button } from "@formbricks/ui/Button";
import LoadSegmentModal from "@formbricks/ui/Targeting/LoadSegmentModal";
import SaveAsNewSegmentModal from "@formbricks/ui/Targeting/SaveAsNewSegmentModal";
import SegmentTitle from "@formbricks/ui/Targeting/SegmentTitle";
import TargetingIndicator from "@formbricks/ui/Targeting/TargetingIndicator";
import { LoadSegmentModal } from "@formbricks/ui/Targeting/LoadSegmentModal";
import { SaveAsNewSegmentModal } from "@formbricks/ui/Targeting/SaveAsNewSegmentModal";
import { SegmentTitle } from "@formbricks/ui/Targeting/SegmentTitle";
import { TargetingIndicator } from "@formbricks/ui/Targeting/TargetingIndicator";
import {
cloneSegmentAction,
@@ -28,8 +28,8 @@ import {
updateSegmentAction,
} from "../lib/actions";
import { ACTIONS_TO_EXCLUDE } from "../lib/constants";
import AddFilterModal from "./AddFilterModal";
import SegmentEditor from "./SegmentEditor";
import { AddFilterModal } from "./AddFilterModal";
import { SegmentEditor } from "./SegmentEditor";
interface UserTargetingAdvancedCardProps {
localSurvey: TSurvey;
@@ -41,7 +41,7 @@ interface UserTargetingAdvancedCardProps {
initialSegment?: TSegment;
}
export function AdvancedTargetingCard({
export const AdvancedTargetingCard = ({
localSurvey,
setLocalSurvey,
environmentId,
@@ -49,7 +49,7 @@ export function AdvancedTargetingCard({
attributeClasses,
segments,
initialSegment,
}: UserTargetingAdvancedCardProps) {
}: UserTargetingAdvancedCardProps) => {
const router = useRouter();
const [open, setOpen] = useState(false);
const [segment, setSegment] = useState<TSegment | null>(localSurvey.segment);
@@ -413,4 +413,4 @@ export function AdvancedTargetingCard({
</Collapsible.CollapsibleContent>
</Collapsible.Root>
);
}
};
@@ -14,8 +14,8 @@ import { Input } from "@formbricks/ui/Input";
import { Modal } from "@formbricks/ui/Modal";
import { createSegmentAction } from "../lib/actions";
import AddFilterModal from "./AddFilterModal";
import SegmentFilters from "./SegmentEditor";
import { AddFilterModal } from "./AddFilterModal";
import { SegmentEditor } from "./SegmentEditor";
type TCreateSegmentModalProps = {
environmentId: string;
@@ -23,7 +23,8 @@ type TCreateSegmentModalProps = {
attributeClasses: TAttributeClass[];
actionClasses: TActionClass[];
};
const CreateSegmentModal = ({
export const CreateSegmentModal = ({
environmentId,
actionClasses,
attributeClasses,
@@ -191,7 +192,7 @@ const CreateSegmentModal = ({
</div>
)}
<SegmentFilters
<SegmentEditor
environmentId={environmentId}
segment={segment}
setSegment={setSegment}
@@ -249,5 +250,3 @@ const CreateSegmentModal = ({
</>
);
};
export default CreateSegmentModal;
@@ -23,8 +23,8 @@ import {
DropdownMenuTrigger,
} from "@formbricks/ui/DropdownMenu";
import AddFilterModal from "./AddFilterModal";
import SegmentFilter from "./SegmentFilter";
import { AddFilterModal } from "./AddFilterModal";
import { SegmentFilter } from "./SegmentFilter";
type TSegmentEditorProps = {
group: TBaseFilters;
@@ -37,7 +37,7 @@ type TSegmentEditorProps = {
viewOnly?: boolean;
};
const SegmentEditor = ({
export const SegmentEditor = ({
group,
environmentId,
setSegment,
@@ -261,5 +261,3 @@ const SegmentEditor = ({
</div>
);
};
export default SegmentEditor;
@@ -62,7 +62,7 @@ import {
import { Input } from "@formbricks/ui/Input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@formbricks/ui/Select";
import AddFilterModal from "./AddFilterModal";
import { AddFilterModal } from "./AddFilterModal";
type TSegmentFilterProps = {
connector: TSegmentConnector;
@@ -944,7 +944,7 @@ const DeviceFilter = ({
);
};
const SegmentFilter = ({
export const SegmentFilter = ({
resource,
connector,
environmentId,
@@ -1112,5 +1112,3 @@ const SegmentFilter = ({
return <div>Unknown filter type</div>;
}
};
export default SegmentFilter;
@@ -12,11 +12,11 @@ import { TAttributeClass } from "@formbricks/types/attributeClasses";
import { TBaseFilter, TSegment, TSegmentWithSurveyNames, ZSegmentFilters } from "@formbricks/types/segment";
import { Button } from "@formbricks/ui/Button";
import { Input } from "@formbricks/ui/Input";
import ConfirmDeleteSegmentModal from "@formbricks/ui/Targeting/ConfirmDeleteSegmentModal";
import { ConfirmDeleteSegmentModal } from "@formbricks/ui/Targeting/ConfirmDeleteSegmentModal";
import { deleteSegmentAction, updateSegmentAction } from "../lib/actions";
import AddFilterModal from "./AddFilterModal";
import SegmentEditor from "./SegmentEditor";
import { AddFilterModal } from "./AddFilterModal";
import { SegmentEditor } from "./SegmentEditor";
type TSegmentSettingsTabProps = {
environmentId: string;
@@ -27,7 +27,7 @@ type TSegmentSettingsTabProps = {
actionClasses: TActionClass[];
};
const SegmentSettings = ({
export const SegmentSettings = ({
environmentId,
initialSegment,
setOpen,
@@ -246,5 +246,3 @@ const SegmentSettings = ({
</>
);
};
export default SegmentSettings;
+1 -3
View File
@@ -13,7 +13,7 @@ const stripe = new Stripe(env.STRIPE_SECRET_KEY!, {
const webhookSecret: string = env.STRIPE_WEBHOOK_SECRET!;
const webhookHandler = async (requestBody: string, stripeSignature: string) => {
export const webhookHandler = async (requestBody: string, stripeSignature: string) => {
let event: Stripe.Event;
try {
@@ -36,5 +36,3 @@ const webhookHandler = async (requestBody: string, stripeSignature: string) => {
}
return { status: 200, message: { received: true } };
};
export default webhookHandler;
-2
View File
@@ -61,5 +61,3 @@ export const reportUsageToStripe = async (
return { status: 500, data: "Something went wrong: " + error };
}
};
export default reportUsageToStripe;
@@ -68,7 +68,7 @@ const validateLanguages = (languages: TLanguage[]) => {
return true;
};
export default function EditLanguage({ product, environmentId }: EditLanguageProps) {
export const EditLanguage = ({ product, environmentId }: EditLanguageProps) => {
const [languages, setLanguages] = useState<TLanguage[]>(product.languages);
const [isEditing, setIsEditing] = useState(false);
const [confirmationModal, setConfirmationModal] = useState({
@@ -194,7 +194,7 @@ export default function EditLanguage({ product, environmentId }: EditLanguagePro
/>
</div>
);
}
};
const AliasTooltip = () => {
return (
@@ -12,12 +12,12 @@ interface LanguageIndicatorProps {
setSelectedLanguageCode: (languageCode: string) => void;
setFirstRender?: (firstRender: boolean) => void;
}
export function LanguageIndicator({
export const LanguageIndicator = ({
surveyLanguages,
selectedLanguageCode,
setSelectedLanguageCode,
setFirstRender,
}: LanguageIndicatorProps) {
}: LanguageIndicatorProps) => {
const [showLanguageDropdown, setShowLanguageDropdown] = useState(false);
const toggleDropdown = () => setShowLanguageDropdown((prev) => !prev);
const languageDropdownRef = useRef(null);
@@ -71,4 +71,4 @@ export function LanguageIndicator({
)}
</div>
);
}
};
@@ -17,11 +17,11 @@ interface LanguageSwitchProps {
selectedLanguageCode: string;
setSelectedLanguageCode: (language: string) => void;
}
export default function LanguageSwitch({
export const LanguageSwitch = ({
surveyLanguages,
selectedLanguageCode,
setSelectedLanguageCode,
}: LanguageSwitchProps) {
}: LanguageSwitchProps) => {
if (selectedLanguageCode === "default") {
selectedLanguageCode =
surveyLanguages.find((surveyLanguage) => {
@@ -64,4 +64,4 @@ export default function LanguageSwitch({
</DropdownMenu>
</div>
);
}
};
+10 -10
View File
@@ -14,11 +14,11 @@ import { getProduct } from "@formbricks/lib/product/service";
import { AuthorizationError } from "@formbricks/types/errors";
import { TLanguageInput } from "@formbricks/types/product";
export async function createLanguageAction(
export const createLanguageAction = async (
productId: string,
environmentId: string,
languageInput: TLanguageInput
) {
) => {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -31,9 +31,9 @@ export async function createLanguageAction(
if (!hasCreateOrUpdateAccess) throw new AuthorizationError("Not authorized");
return await createLanguage(productId, environmentId, languageInput);
}
};
export async function deleteLanguageAction(productId: string, environmentId: string, languageId: string) {
export const deleteLanguageAction = async (productId: string, environmentId: string, languageId: string) => {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -46,9 +46,9 @@ export async function deleteLanguageAction(productId: string, environmentId: str
if (!hasCreateOrUpdateAccess) throw new AuthorizationError("Not authorized");
return await deleteLanguage(environmentId, languageId);
}
};
export async function getSurveysUsingGivenLanguageAction(productId: string, languageId: string) {
export const getSurveysUsingGivenLanguageAction = async (productId: string, languageId: string) => {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -56,14 +56,14 @@ export async function getSurveysUsingGivenLanguageAction(productId: string, lang
if (!isAuthorized) throw new AuthorizationError("Not authorized");
return await getSurveysUsingGivenLanguage(languageId);
}
};
export async function updateLanguageAction(
export const updateLanguageAction = async (
productId: string,
environmentId: string,
languageId: string,
languageInput: TLanguageInput
) {
) => {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
@@ -76,4 +76,4 @@ export async function updateLanguageAction(
if (!hasCreateOrUpdateAccess) throw new AuthorizationError("Not authorized");
return await updateLanguage(environmentId, languageId, languageInput);
}
};
@@ -72,11 +72,11 @@ export const removePageUrlEventListeners = (): void => {
arePageUrlEventListenersAdded = false;
};
export function checkUrlMatch(
export const checkUrlMatch = (
url: string,
pageUrlValue: string,
pageUrlRule: TActionClassPageUrlRule
): Result<boolean, InvalidMatchTypeError> {
): Result<boolean, InvalidMatchTypeError> => {
switch (pageUrlRule) {
case "exactMatch":
return ok(url === pageUrlValue);
@@ -96,7 +96,7 @@ export function checkUrlMatch(
message: "Invalid match type",
});
}
}
};
const evaluateNoCodeConfig = (targetElement: HTMLElement, action: TActionClass): boolean => {
const innerHtml = action.noCodeConfig?.innerHtml?.value;
+1 -1
View File
@@ -1,6 +1,6 @@
import { FormbricksAPI } from "@formbricks/api";
import { ResponseQueue } from "@formbricks/lib/responseQueue";
import SurveyState from "@formbricks/lib/surveyState";
import { SurveyState } from "@formbricks/lib/surveyState";
import { getStyling } from "@formbricks/lib/utils/styling";
import { TResponseUpdate } from "@formbricks/types/responses";
import { TSurvey } from "@formbricks/types/surveys";
@@ -6,7 +6,7 @@ import { err } from "./errors";
let exitIntentListenerAdded = false;
let exitIntentListenerWrapper = async function (e: MouseEvent, packageType: TJsPackageType) {
let exitIntentListenerWrapper = async (e: MouseEvent, packageType: TJsPackageType) => {
if (e.clientY <= 0) {
const trackResult =
packageType === "app"
+2 -8
View File
@@ -22,17 +22,11 @@ export const wrap =
(result: Result<T>): Result<R> =>
result.ok === true ? { ok: true, value: fn(result.value) } : result;
export function match<TSuccess, TError, TReturn>(
export const match = <TSuccess, TError, TReturn>(
result: Result<TSuccess, TError>,
onSuccess: (value: TSuccess) => TReturn,
onError: (error: TError) => TReturn
) {
if (result.ok === true) {
return onSuccess(result.value);
}
return onError(result.error);
}
): TReturn => (result.ok === true ? onSuccess(result.value) : onError(result.error));
/*
Usage:
@@ -72,11 +72,11 @@ export const removePageUrlEventListeners = (): void => {
arePageUrlEventListenersAdded = false;
};
export function checkUrlMatch(
export const checkUrlMatch = (
url: string,
pageUrlValue: string,
pageUrlRule: TActionClassPageUrlRule
): Result<boolean, InvalidMatchTypeError> {
): Result<boolean, InvalidMatchTypeError> => {
switch (pageUrlRule) {
case "exactMatch":
return ok(url === pageUrlValue);
@@ -96,7 +96,7 @@ export function checkUrlMatch(
message: "Invalid match type",
});
}
}
};
const evaluateNoCodeConfig = (targetElement: HTMLElement, action: TActionClass): boolean => {
const innerHtml = action.noCodeConfig?.innerHtml?.value;
+1 -1
View File
@@ -1,6 +1,6 @@
import { FormbricksAPI } from "@formbricks/api";
import { ResponseQueue } from "@formbricks/lib/responseQueue";
import SurveyState from "@formbricks/lib/surveyState";
import { SurveyState } from "@formbricks/lib/surveyState";
import { getStyling } from "@formbricks/lib/utils/styling";
import { TJSWebsiteStateDisplay } from "@formbricks/types/js";
import { TResponseUpdate } from "@formbricks/types/responses";
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -7,7 +7,7 @@
e.parentNode.insertBefore(t, e),
setTimeout(function () {
formbricks.init({
environmentId: "clvzbzhhi000d10cpk0vtopz4",
environmentId: "clw6ehzd5008zrx0nmrix2pnw",
apiHost: "http://localhost:3000",
});
}, 500);
+2 -2
View File
@@ -10,7 +10,7 @@ declare global {
}
// load the sdk, return the result
async function loadFormbricksAppSDK(apiHost: string): Promise<Result<void>> {
const loadFormbricksAppSDK = async (apiHost: string): Promise<Result<void>> => {
if (!window.formbricks) {
const res = await fetch(`${apiHost}/api/packages/app`);
@@ -52,7 +52,7 @@ async function loadFormbricksAppSDK(apiHost: string): Promise<Result<void>> {
}
return { ok: true, data: undefined };
}
};
type FormbricksAppMethods = {
[K in keyof TFormbricksApp]: TFormbricksApp[K] extends Function ? K : never;
+2 -2
View File
@@ -10,7 +10,7 @@ declare global {
}
// load the sdk, return the result
async function loadFormbricksWebsiteSDK(apiHost: string): Promise<Result<void>> {
const loadFormbricksWebsiteSDK = async (apiHost: string): Promise<Result<void>> => {
if (!window.formbricks) {
const res = await fetch(`${apiHost}/api/packages/website`);
@@ -52,7 +52,7 @@ async function loadFormbricksWebsiteSDK(apiHost: string): Promise<Result<void>>
}
return { ok: true, data: undefined };
}
};
type FormbricksWebsiteMethods = {
[K in keyof TFormbricksWebsite]: TFormbricksWebsite[K] extends Function ? K : never;
+4 -4
View File
@@ -3,15 +3,15 @@ import { compare, hash } from "bcryptjs";
import { prisma } from "@formbricks/database";
import { AuthenticationError } from "@formbricks/types/errors";
export async function hashPassword(password: string) {
export const hashPassword = async (password: string) => {
const hashedPassword = await hash(password, 12);
return hashedPassword;
}
};
export async function verifyPassword(password: string, hashedPassword: string) {
export const verifyPassword = async (password: string, hashedPassword: string) => {
const isValid = await compare(password, hashedPassword);
return isValid;
}
};
export const hasTeamAccess = async (userId: string, teamId: string) => {
const membership = await prisma.membership.findUnique({
+4 -4
View File
@@ -1,11 +1,11 @@
import { compare, hash } from "bcryptjs";
export async function hashPassword(password: string) {
export const hashPassword = async (password: string) => {
const hashedPassword = await hash(password, 12);
return hashedPassword;
}
};
export async function verifyPassword(password: string, hashedPassword: string) {
export const verifyPassword = async (password: string, hashedPassword: string) => {
const isValid = await compare(password, hashedPassword);
return isValid;
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
export const cn = (...inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
}
};
+8 -8
View File
@@ -16,7 +16,7 @@ const IV_LENGTH = 16; // AES blocksize
*
* @returns Encrypted value using key
*/
export const symmetricEncrypt = function (text: string, key: string) {
export const symmetricEncrypt = (text: string, key: string) => {
const _key = Buffer.from(key, BUFFER_ENCODING);
const iv = crypto.randomBytes(IV_LENGTH);
@@ -33,7 +33,7 @@ export const symmetricEncrypt = function (text: string, key: string) {
* @param text Value to decrypt
* @param key Key used to decrypt value must be 32 bytes for AES256 encryption algorithm
*/
export const symmetricDecrypt = function (text: string, key: string) {
export const symmetricDecrypt = (text: string, key: string) => {
const _key = Buffer.from(key, BUFFER_ENCODING);
const components = text.split(":");
@@ -62,19 +62,19 @@ export const decryptAES128 = (encryptionKey: string, data: string): string => {
return decrypted;
};
export function generateLocalSignedUrl(
export const generateLocalSignedUrl = (
fileName: string,
environmentId: string,
fileType: string
): { signature: string; uuid: string; timestamp: number } {
): { signature: string; uuid: string; timestamp: number } => {
const uuid = randomBytes(16).toString("hex");
const timestamp = Date.now();
const data = `${uuid}:${fileName}:${environmentId}:${fileType}:${timestamp}`;
const signature = createHmac("sha256", ENCRYPTION_KEY!).update(data).digest("hex");
return { signature, uuid, timestamp };
}
};
export function validateLocalSignedUrl(
export const validateLocalSignedUrl = (
uuid: string,
fileName: string,
environmentId: string,
@@ -82,7 +82,7 @@ export function validateLocalSignedUrl(
timestamp: number,
signature: string,
secret: string
): boolean {
): boolean => {
const data = `${uuid}:${fileName}:${environmentId}:${fileType}:${timestamp}`;
const expectedSignature = createHmac("sha256", secret).update(data).digest("hex");
@@ -96,4 +96,4 @@ export function validateLocalSignedUrl(
}
return true;
}
};
@@ -11,7 +11,7 @@ export const mockId = "ars2tjk8hsi8oqk1uac00mo8";
export const mockPersonId = "clqnj99r9000008lebgf8734j";
export const mockResponseId = "clqnfg59i000208i426pb4wcv";
function createMockDisplay(overrides = {}) {
const createMockDisplay = (overrides = {}) => {
return {
id: mockDisplayId,
createdAt: new Date(),
@@ -22,7 +22,7 @@ function createMockDisplay(overrides = {}) {
status: null,
...overrides,
};
}
};
export const mockDisplay = createMockDisplay();
+5 -5
View File
@@ -23,7 +23,7 @@ import { validateInputs } from "../utils/validate";
const { google } = require("googleapis");
async function fetchSpreadsheets(auth: any) {
const fetchSpreadsheets = async (auth: any) => {
const authClient = authorize(auth);
const service = google.drive({ version: "v3", auth: authClient });
try {
@@ -35,7 +35,7 @@ async function fetchSpreadsheets(auth: any) {
} catch (err) {
throw err;
}
}
};
export const getSpreadSheets = async (environmentId: string): Promise<TIntegrationItem[]> => {
validateInputs([environmentId, ZId]);
@@ -57,11 +57,11 @@ export const getSpreadSheets = async (environmentId: string): Promise<TIntegrati
throw error;
}
};
export async function writeData(
export const writeData = async (
credentials: TIntegrationGoogleSheetsCredential,
spreadsheetId: string,
values: string[][]
) {
) => {
validateInputs(
[credentials, ZIntegrationGoogleSheetsCredential],
[spreadsheetId, ZString],
@@ -106,7 +106,7 @@ export async function writeData(
}
throw error;
}
}
};
const authorize = (credentials: any) => {
const client_id = GOOGLE_SHEETS_CLIENT_ID;
+2 -2
View File
@@ -77,9 +77,9 @@ export const createI18nString = (
};
// Type guard to check if an object is an I18nString
export function isI18nObject(obj: any): obj is TI18nString {
export const isI18nObject = (obj: any): obj is TI18nString => {
return typeof obj === "object" && obj !== null && Object.keys(obj).includes("default");
}
};
export const isLabelValidForAllLanguages = (label: TI18nString, languages: string[]): boolean => {
return languages.every((language) => label[language] && label[language].trim() !== "");
+3 -3
View File
@@ -13,10 +13,10 @@ import { ITEMS_PER_PAGE } from "../constants";
import { validateInputs } from "../utils/validate";
import { integrationCache } from "./cache";
export async function createOrUpdateIntegration(
export const createOrUpdateIntegration = async (
environmentId: string,
integrationData: TIntegrationInput
): Promise<TIntegration> {
): Promise<TIntegration> => {
validateInputs([environmentId, ZId]);
try {
@@ -49,7 +49,7 @@ export async function createOrUpdateIntegration(
}
throw error;
}
}
};
export const getIntegrations = (environmentId: string, page?: number): Promise<TIntegration[]> =>
cache(
+8 -8
View File
@@ -4,27 +4,27 @@ import { prisma } from "@formbricks/database";
import { env } from "./env";
export function createToken(userId: string, userEmail: string, options = {}): string {
export const createToken = (userId: string, userEmail: string, options = {}): string => {
return jwt.sign({ id: userId }, env.NEXTAUTH_SECRET + userEmail, options);
}
export function createTokenForLinkSurvey(surveyId: string, userEmail: string): string {
};
export const createTokenForLinkSurvey = (surveyId: string, userEmail: string): string => {
return jwt.sign({ email: userEmail }, env.NEXTAUTH_SECRET + surveyId);
}
};
export const createInviteToken = (inviteId: string, email: string, options = {}): string => {
return jwt.sign({ inviteId, email }, env.NEXTAUTH_SECRET, options);
};
export function verifyTokenForLinkSurvey(token: string, surveyId: string) {
export const verifyTokenForLinkSurvey = (token: string, surveyId: string) => {
try {
const payload = jwt.verify(token, process.env.NEXTAUTH_SECRET + surveyId);
return (payload as jwt.JwtPayload).email || null;
} catch (err) {
return null;
}
}
};
export async function verifyToken(token: string, userEmail: string = ""): Promise<JwtPayload> {
export const verifyToken = async (token: string, userEmail: string = ""): Promise<JwtPayload> => {
if (!token) {
throw new Error("No token found");
}
@@ -45,7 +45,7 @@ export async function verifyToken(token: string, userEmail: string = ""): Promis
}
return jwt.verify(token, env.NEXTAUTH_SECRET + userEmail) as JwtPayload;
}
};
export const verifyInviteToken = (token: string): { inviteId: string; email: string } => {
try {
+7 -7
View File
@@ -8,7 +8,7 @@ import { ENCRYPTION_KEY } from "../constants";
import { symmetricDecrypt } from "../crypto";
import { getIntegrationByType } from "../integration/service";
async function fetchPages(config: TIntegrationNotionConfig) {
const fetchPages = async (config: TIntegrationNotionConfig) => {
try {
const res = await fetch("https://api.notion.com/v1/search", {
headers: getHeaders(config),
@@ -25,7 +25,7 @@ async function fetchPages(config: TIntegrationNotionConfig) {
} catch (error) {
throw error;
}
}
};
export const getNotionDatabases = async (environmentId: string): Promise<TIntegrationNotionDatabase[]> => {
let results: TIntegrationNotionDatabase[] = [];
@@ -40,11 +40,11 @@ export const getNotionDatabases = async (environmentId: string): Promise<TIntegr
}
};
export async function writeData(
export const writeData = async (
databaseId: string,
properties: Record<string, Object>,
config: TIntegrationNotionConfig
) {
) => {
try {
await fetch(`https://api.notion.com/v1/pages`, {
headers: getHeaders(config),
@@ -59,9 +59,9 @@ export async function writeData(
} catch (error) {
throw error;
}
}
};
function getHeaders(config: TIntegrationNotionConfig) {
const getHeaders = (config: TIntegrationNotionConfig) => {
const decryptedToken = symmetricDecrypt(config.key.access_token, ENCRYPTION_KEY!);
return {
Accept: "application/json",
@@ -69,4 +69,4 @@ function getHeaders(config: TIntegrationNotionConfig) {
Authorization: `Bearer ${decryptedToken}`,
"Notion-Version": "2022-06-28",
};
}
};
+2 -2
View File
@@ -25,12 +25,12 @@ import { sanitizeString } from "../strings";
import { getTodaysDateTimeFormatted } from "../time";
import { evaluateCondition } from "../utils/evaluateLogic";
export function calculateTtcTotal(ttc: TResponseTtc) {
export const calculateTtcTotal = (ttc: TResponseTtc) => {
const result = { ...ttc };
result._total = Object.values(result).reduce((acc: number, val: number) => acc + val, 0);
return result;
}
};
export const buildWhereClause = (filterCriteria?: TResponseFilterCriteria) => {
const whereClause: Prisma.ResponseWhereInput["AND"] = [];
+1 -1
View File
@@ -1,7 +1,7 @@
import { FormbricksAPI } from "@formbricks/api";
import { TResponseUpdate } from "@formbricks/types/responses";
import SurveyState from "./surveyState";
import { SurveyState } from "./surveyState";
import { delay } from "./utils";
interface QueueConfig {
+2 -2
View File
@@ -27,9 +27,9 @@ import {
updateSegment,
} from "../service";
function addOrSubractDays(date: Date, number: number) {
const addOrSubractDays = (date: Date, number: number) => {
return new Date(new Date().setDate(date.getDate() - number));
}
};
beforeEach(() => {
prisma.segment.findUnique.mockResolvedValue(mockSegmentPrisma);
+3 -3
View File
@@ -52,12 +52,12 @@ export const getSlackChannels = async (environmentId: string): Promise<TIntegrat
}
};
export async function writeDataToSlack(
export const writeDataToSlack = async (
credentials: TIntegrationSlackCredential,
channelId: string,
values: string[][],
surveyName: string | undefined
) {
) => {
try {
const [responses, questions] = values;
let blockResponse = [
@@ -117,4 +117,4 @@ export async function writeDataToSlack(
}
throw error;
}
}
};
+2 -2
View File
@@ -1,9 +1,9 @@
export function capitalizeFirstLetter(string: string | null = "") {
export const capitalizeFirstLetter = (string: string | null = "") => {
if (string === null) {
return "";
}
return string.charAt(0).toUpperCase() + string.slice(1);
}
};
// write a function that takes a string and truncates it to the specified length
export const truncate = (str: string, length: number) => {
+2 -2
View File
@@ -519,7 +519,7 @@ export const updateSurvey = async (updatedSurvey: TSurvey): Promise<TSurvey> =>
}
};
export async function deleteSurvey(surveyId: string) {
export const deleteSurvey = async (surveyId: string) => {
validateInputs([surveyId, ZId]);
try {
@@ -582,7 +582,7 @@ export async function deleteSurvey(surveyId: string) {
throw error;
}
}
};
export const createSurvey = async (environmentId: string, surveyBody: TSurveyInput): Promise<TSurvey> => {
validateInputs([environmentId, ZId]);
-2
View File
@@ -94,5 +94,3 @@ export class SurveyState {
this.responseAcc = { finished: false, data: {}, ttc: {} };
}
}
export default SurveyState;
+2 -2
View File
@@ -117,7 +117,7 @@ export const getTodaysDateTimeFormatted = (seperator: string) => {
return [formattedDate, formattedTime].join(seperator);
};
export function convertDatesInObject(obj: any) {
export const convertDatesInObject = (obj: any) => {
for (let key in obj) {
if ((key === "createdAt" || key === "updatedAt") && !isNaN(Date.parse(obj[key]))) {
obj[key] = new Date(obj[key]);
@@ -125,4 +125,4 @@ export function convertDatesInObject(obj: any) {
convertDatesInObject(obj[key]);
}
}
}
};
+2 -2
View File
@@ -66,7 +66,7 @@ export const mixColor = (hexColor: string, mixWithHex: string, weight: number):
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
};
export function isLight(color: string) {
export const isLight = (color: string) => {
let r: number | undefined, g: number | undefined, b: number | undefined;
if (color.length === 4) {
@@ -82,4 +82,4 @@ export function isLight(color: string) {
throw new Error("Invalid color");
}
return r * 0.299 + g * 0.587 + b * 0.114 > 128;
}
};
+2 -2
View File
@@ -57,7 +57,7 @@ export const getOrdinalDate = (date: number) => {
return date + "th";
};
export function isValidDateString(value: string) {
export const isValidDateString = (value: string) => {
const regex = /^(?:\d{4}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/;
if (!regex.test(value)) {
@@ -66,4 +66,4 @@ export function isValidDateString(value: string) {
const date = new Date(value);
return date;
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
import { TSurveyLogic } from "@formbricks/types/surveys";
export function evaluateCondition(logic: TSurveyLogic, responseValue: any): boolean {
export const evaluateCondition = (logic: TSurveyLogic, responseValue: any): boolean => {
switch (logic.condition) {
case "equals":
return (
@@ -52,4 +52,4 @@ export function evaluateCondition(logic: TSurveyLogic, responseValue: any): bool
default:
return false;
}
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
export type MatchType = "exactMatch" | "contains" | "startsWith" | "endsWith" | "notMatch" | "notContains";
export function testURLmatch(testUrl: string, pageUrlValue: string, pageUrlRule: MatchType): string {
export const testURLmatch = (testUrl: string, pageUrlValue: string, pageUrlRule: MatchType): string => {
switch (pageUrlRule) {
case "exactMatch":
return testUrl === pageUrlValue ? "yes" : "no";
@@ -17,4 +17,4 @@ export function testURLmatch(testUrl: string, pageUrlValue: string, pageUrlRule:
default:
throw new Error("Invalid match type");
}
}
};
@@ -6,7 +6,7 @@ interface BackButtonProps {
tabIndex?: number;
}
export function BackButton({ onClick, backButtonLabel, tabIndex = 2 }: BackButtonProps) {
export const BackButton = ({ onClick, backButtonLabel, tabIndex = 2 }: BackButtonProps) => {
return (
<button
tabIndex={tabIndex}
@@ -18,4 +18,4 @@ export function BackButton({ onClick, backButtonLabel, tabIndex = 2 }: BackButto
{backButtonLabel || "Back"}
</button>
);
}
};
@@ -9,14 +9,14 @@ interface SubmitButtonProps {
type?: "submit" | "button";
}
function SubmitButton({
export const SubmitButton = ({
buttonLabel,
isLastQuestion,
onClick = () => {},
tabIndex = 1,
focus = false,
type = "submit",
}: SubmitButtonProps) {
}: SubmitButtonProps) => {
const buttonRef = useCallback(
(currentButton: HTMLButtonElement | null) => {
if (currentButton && focus) {
@@ -39,5 +39,4 @@ function SubmitButton({
{buttonLabel || (isLastQuestion ? "Finish" : "Next")}
</button>
);
}
export default SubmitButton;
};
@@ -2,7 +2,7 @@ interface AutoCloseProgressBarProps {
autoCloseTimeout: number;
}
export function AutoCloseProgressBar({ autoCloseTimeout }: AutoCloseProgressBarProps) {
export const AutoCloseProgressBar = ({ autoCloseTimeout }: AutoCloseProgressBarProps) => {
return (
<div className="bg-accent-bg h-2 w-full overflow-hidden rounded-full">
<div
@@ -13,4 +13,4 @@ export function AutoCloseProgressBar({ autoCloseTimeout }: AutoCloseProgressBarP
}}></div>
</div>
);
}
};
@@ -9,7 +9,7 @@ interface CalEmbedProps {
onSuccessfulBooking: () => void;
}
export default function CalEmbed({ question, onSuccessfulBooking }: CalEmbedProps) {
export const CalEmbed = ({ question, onSuccessfulBooking }: CalEmbedProps) => {
const cal = useMemo(() => {
const calInline = snippet("https://cal.com/embed.js");
@@ -53,4 +53,4 @@ export default function CalEmbed({ question, onSuccessfulBooking }: CalEmbedProp
<div id="fb-cal-embed" className={cn("border-border rounded-lg border")} />
</div>
);
}
};
@@ -17,7 +17,7 @@ interface MultipleFileInputProps {
allowMultipleFiles?: boolean;
}
export default function FileInput({
export const FileInput = ({
allowedFileExtensions,
surveyId,
onUploadCallback,
@@ -25,7 +25,7 @@ export default function FileInput({
fileUrls,
maxSizeInMB,
allowMultipleFiles,
}: MultipleFileInputProps) {
}: MultipleFileInputProps) => {
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const [isUploading, setIsUploading] = useState(false);
@@ -314,4 +314,4 @@ export default function FileInput({
</div>
</div>
);
}
};
@@ -7,12 +7,12 @@ interface HeadlineProps {
alignTextCenter?: boolean;
}
export default function Headline({
export const Headline = ({
headline,
questionId,
required = true,
alignTextCenter = false,
}: HeadlineProps) {
}: HeadlineProps) => {
return (
<label htmlFor={questionId} className="text-heading mb-1.5 block text-base font-semibold leading-6">
<div className={`flex items-center ${alignTextCenter ? "justify-center" : "justify-between"}`}>
@@ -27,4 +27,4 @@ export default function Headline({
</div>
</label>
);
}
};
@@ -5,7 +5,7 @@ interface HtmlBodyProps {
questionId: string;
}
export default function HtmlBody({ htmlString, questionId }: HtmlBodyProps) {
export const HtmlBody = ({ htmlString, questionId }: HtmlBodyProps) => {
const [safeHtml, setSafeHtml] = useState("");
useEffect(() => {
@@ -25,4 +25,4 @@ export default function HtmlBody({ htmlString, questionId }: HtmlBodyProps) {
className="fb-htmlbody break-words" // styles are in global.css
dangerouslySetInnerHTML={{ __html: safeHtml }}></label>
);
}
};
@@ -1,4 +1,4 @@
export default function Progress({ progress }: { progress: number }) {
export const Progress = ({ progress }: { progress: number }) => {
return (
<div className="bg-accent-bg h-2 w-full overflow-hidden rounded-full">
<div
@@ -6,4 +6,4 @@ export default function Progress({ progress }: { progress: number }) {
style={{ width: `${Math.floor(progress * 100)}%` }}></div>
</div>
);
}
};
@@ -3,7 +3,7 @@ import { useCallback, useMemo } from "preact/hooks";
import { TSurvey } from "@formbricks/types/surveys";
import Progress from "./Progress";
import { Progress } from "./Progress";
interface ProgressBarProps {
survey: TSurvey;
@@ -7,7 +7,7 @@ interface RedirectCountDownProps {
isRedirectDisabled: boolean;
}
export default function RedirectCountDown({ redirectUrl, isRedirectDisabled }: RedirectCountDownProps) {
export const RedirectCountDown = ({ redirectUrl, isRedirectDisabled }: RedirectCountDownProps) => {
const [timeRemaining, setTimeRemaining] = useState(REDIRECT_TIMEOUT);
useEffect(() => {
@@ -41,4 +41,4 @@ export default function RedirectCountDown({ redirectUrl, isRedirectDisabled }: R
</div>
</div>
);
}
};
@@ -1,4 +1,4 @@
import SubmitButton from "@/components/buttons/SubmitButton";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { processResponseData } from "@formbricks/lib/responses";
import { type TResponseData } from "@formbricks/types/responses";
@@ -1,7 +1,7 @@
export default function Subheader({ subheader, questionId }: { subheader?: string; questionId: string }) {
export const Subheader = ({ subheader, questionId }: { subheader?: string; questionId: string }) => {
return (
<p htmlFor={questionId} className="text-subheading block break-words text-sm font-normal leading-5">
{subheader}
</p>
);
}
};
@@ -4,7 +4,7 @@ import { SurveyInlineProps } from "@formbricks/types/formbricksSurveys";
import { Survey } from "./Survey";
export function SurveyInline(props: SurveyInlineProps) {
export const SurveyInline = (props: SurveyInlineProps) => {
const [isMobile, setIsMobile] = useState(window.innerWidth < 768); // Assuming 768px as a breakpoint for mobile
useEffect(() => {
@@ -29,4 +29,4 @@ export function SurveyInline(props: SurveyInlineProps) {
)}
</div>
);
}
};
@@ -1,11 +1,11 @@
import Modal from "@/components/wrappers/Modal";
import { Modal } from "@/components/wrappers/Modal";
import { useState } from "preact/hooks";
import { SurveyModalProps } from "@formbricks/types/formbricksSurveys";
import { Survey } from "./Survey";
export function SurveyModal({
export const SurveyModal = ({
survey,
isBrandingEnabled,
getSetIsError,
@@ -23,7 +23,7 @@ export function SurveyModal({
languageCode,
responseCount,
styling,
}: SurveyModalProps) {
}: SurveyModalProps) => {
const [isOpen, setIsOpen] = useState(true);
const close = () => {
@@ -74,4 +74,4 @@ export function SurveyModal({
</Modal>
</div>
);
}
};
@@ -1,9 +1,9 @@
import Button from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { LoadingSpinner } from "@/components/general/LoadingSpinner";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import RedirectCountDown from "@/components/general/RedirectCountdown";
import Subheader from "@/components/general/Subheader";
import { RedirectCountDown } from "@/components/general/RedirectCountdown";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
@@ -76,7 +76,7 @@ export const ThankYouCard = ({
<RedirectCountDown redirectUrl={redirectUrl} isRedirectDisabled={isRedirectDisabled} />
{buttonLabel && (
<div className="mt-6 flex w-full flex-col items-center justify-center space-y-4">
<Button
<SubmitButton
buttonLabel={getLocalizedValue(buttonLabel, languageCode)}
isLastQuestion={false}
focus={!isInIframe}
@@ -1,4 +1,4 @@
import SubmitButton from "@/components/buttons/SubmitButton";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { calculateElementIdx } from "@/lib/utils";
@@ -6,8 +6,8 @@ import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
import { TI18nString, TSurvey } from "@formbricks/types/surveys";
import Headline from "./Headline";
import HtmlBody from "./HtmlBody";
import { Headline } from "./Headline";
import { HtmlBody } from "./HtmlBody";
interface WelcomeCardProps {
headline?: TI18nString;
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
@@ -1,7 +1,7 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import HtmlBody from "@/components/general/HtmlBody";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { HtmlBody } from "@/components/general/HtmlBody";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
@@ -1,9 +1,9 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import CalEmbed from "@/components/general/CalEmbed";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { CalEmbed } from "@/components/general/CalEmbed";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { useCallback, useState } from "preact/hooks";
@@ -1,7 +1,7 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import HtmlBody from "@/components/general/HtmlBody";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { HtmlBody } from "@/components/general/HtmlBody";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
@@ -1,3 +1,5 @@
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
@@ -9,10 +11,8 @@ import { TUploadFileConfig } from "@formbricks/types/storage";
import type { TSurveyFileUploadQuestion } from "@formbricks/types/surveys";
import { BackButton } from "../buttons/BackButton";
import SubmitButton from "../buttons/SubmitButton";
import FileInput from "../general/FileInput";
import Headline from "../general/Headline";
import Subheader from "../general/Subheader";
import { FileInput } from "../general/FileInput";
import { Subheader } from "../general/Subheader";
interface FileUploadQuestionProps {
question: TSurveyFileUploadQuestion;
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { JSX } from "preact";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn, shuffleQuestions } from "@/lib/utils";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn, shuffleQuestions } from "@/lib/utils";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { useState } from "preact/hooks";
@@ -1,8 +1,8 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import Subheader from "@/components/general/Subheader";
import { Subheader } from "@/components/general/Subheader";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
@@ -1,6 +1,6 @@
import { BackButton } from "@/components/buttons/BackButton";
import SubmitButton from "@/components/buttons/SubmitButton";
import Headline from "@/components/general/Headline";
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { Headline } from "@/components/general/Headline";
import { QuestionMedia } from "@/components/general/QuestionMedia";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
@@ -23,7 +23,7 @@ import {
TiredFace,
WearyFace,
} from "../general/Smileys";
import Subheader from "../general/Subheader";
import { Subheader } from "../general/Subheader";
interface RatingQuestionProps {
question: TSurveyRatingQuestion;
@@ -10,7 +10,7 @@ interface AutoCloseProps {
children: React.ReactNode;
}
export function AutoCloseWrapper({ survey, onClose, children }: AutoCloseProps) {
export const AutoCloseWrapper = ({ survey, onClose, children }: AutoCloseProps) => {
const [countDownActive, setCountDownActive] = useState(true);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const isAppSurvey = survey.type === "app" || survey.type === "website";
@@ -53,4 +53,4 @@ export function AutoCloseWrapper({ survey, onClose, children }: AutoCloseProps)
</div>
</div>
);
}
};
@@ -14,14 +14,7 @@ interface ModalProps {
onClose: () => void;
}
export default function Modal({
children,
isOpen,
placement,
clickOutside,
darkOverlay,
onClose,
}: ModalProps) {
export const Modal = ({ children, isOpen, placement, clickOutside, darkOverlay, onClose }: ModalProps) => {
const [show, setShow] = useState(false);
const isCenter = placement === "center";
const modalRef = useRef(null);
@@ -33,7 +26,7 @@ export default function Modal({
useEffect(() => {
if (!isCenter) return;
function handleClickOutside(e: MouseEvent) {
const handleClickOutside = (e: MouseEvent) => {
if (
clickOutside &&
show &&
@@ -42,7 +35,7 @@ export default function Modal({
) {
onClose();
}
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
@@ -97,4 +90,4 @@ export default function Modal({
</div>
</div>
);
}
};
+3 -3
View File
@@ -1,9 +1,9 @@
import { TSurveyLogic } from "@formbricks/types/surveys";
export function evaluateCondition(
export const evaluateCondition = (
logic: TSurveyLogic,
responseValue: string | number | string[] | Record<string, string>
): boolean {
): boolean => {
const isObject = typeof responseValue === "object" && responseValue !== null;
switch (logic.condition) {
case "equals":
@@ -84,4 +84,4 @@ export function evaluateCondition(
default:
return false;
}
}
};
+2 -8
View File
@@ -71,17 +71,11 @@ export const wrap =
* console.log(error); // Error: error happened
* });
*/
export function match<TSuccess, TError, TReturn>(
export const match = <TSuccess, TError, TReturn>(
result: Result<TSuccess, TError>,
onSuccess: (value: TSuccess) => TReturn,
onError: (error: TError) => TReturn
): TReturn {
if (result.ok === true) {
return onSuccess(result.data);
}
return onError(result.error);
}
): TReturn => (result.ok === true ? onSuccess(result.data) : onError(result.error));
/**
* Wraps a function `fn` that may throw an error into a new function that returns a `Result` object.
+3 -3
View File
@@ -15,7 +15,7 @@ interface AdvancedOptionToggleProps {
disabled?: boolean;
}
export function AdvancedOptionToggle({
export const AdvancedOptionToggle = ({
isChecked,
onToggle,
htmlId,
@@ -25,7 +25,7 @@ export function AdvancedOptionToggle({
childBorder,
customContainerClass,
disabled = false,
}: AdvancedOptionToggleProps) {
}: AdvancedOptionToggleProps) => {
return (
<div className={cn("px-4 py-2", customContainerClass)}>
<div className="flex items-center space-x-1">
@@ -47,4 +47,4 @@ export function AdvancedOptionToggle({
)}
</div>
);
}
};
+3 -4
View File
@@ -33,10 +33,7 @@ export type ButtonProps = ButtonBasePropsWithTarget &
export const Button: React.ForwardRefExoticComponent<
React.PropsWithoutRef<ButtonProps> & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement>
> = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonProps>(function Button(
props: ButtonProps,
forwardedRef
) {
> = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonProps>((props: ButtonProps, forwardedRef) => {
const {
loading = false,
variant = "primary",
@@ -193,3 +190,5 @@ const Wrapper = ({
</TooltipProvider>
);
};
Button.displayName = "Button";
+2 -4
View File
@@ -10,7 +10,7 @@ import { cn } from "@formbricks/lib/cn";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
export const Calendar = ({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) => {
return (
<DayPicker
showOutsideDays={showOutsideDays}
@@ -47,7 +47,5 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
{...props}
/>
);
}
};
Calendar.displayName = "Calendar";
export { Calendar };
+2 -2
View File
@@ -3,9 +3,9 @@
import { signOut } from "next-auth/react";
import { useEffect } from "react";
export default function ClientLogout() {
export const ClientLogout = () => {
useEffect(() => {
signOut();
});
return null;
}
};
+2 -4
View File
@@ -18,13 +18,13 @@ interface CodeBlockProps {
showCopyToClipboard?: boolean;
}
const CodeBlock: React.FC<CodeBlockProps> = ({
export const CodeBlock = ({
children,
language,
customEditorClass = "",
customCodeClass = "",
showCopyToClipboard = true,
}) => {
}: CodeBlockProps) => {
useEffect(() => {
Prism.highlightAll();
}, [children]);
@@ -49,5 +49,3 @@ const CodeBlock: React.FC<CodeBlockProps> = ({
</div>
);
};
export default CodeBlock;
+2 -2
View File
@@ -19,7 +19,7 @@ type FormValues = {
name: string;
};
export default function CreateTeamModal({ open, setOpen }: CreateTeamModalProps) {
export const CreateTeamModal = ({ open, setOpen }: CreateTeamModalProps) => {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [teamName, setTeamName] = useState("");
@@ -97,4 +97,4 @@ export default function CreateTeamModal({ open, setOpen }: CreateTeamModalProps)
</div>
</Modal>
);
}
};
+3 -3
View File
@@ -17,7 +17,7 @@ interface CustomDialogProps {
disabled?: boolean;
}
export default function CustomDialog({
export const CustomDialog = ({
open,
setOpen,
title,
@@ -29,7 +29,7 @@ export default function CustomDialog({
onCancel,
cancelBtnText,
disabled,
}: CustomDialogProps) {
}: CustomDialogProps) => {
return (
<Modal open={open} setOpen={setOpen} title={title}>
<p>{text}</p>
@@ -51,4 +51,4 @@ export default function CustomDialog({
</div>
</Modal>
);
}
};
+3 -3
View File
@@ -12,13 +12,13 @@ import { Button } from "../Button";
import { Calendar } from "../Calendar";
import { Popover, PopoverContent, PopoverTrigger } from "../Popover";
export function DatePicker({
export const DatePicker = ({
date,
handleDateChange,
}: {
date?: Date | null;
handleDateChange: (date?: Date) => void;
}) {
}) => {
let formattedDate = date ? new Date(date) : undefined;
const btnRef = useRef<HTMLButtonElement>(null);
@@ -55,4 +55,4 @@ export function DatePicker({
</PopoverContent>
</Popover>
);
}
};
+2 -2
View File
@@ -1,7 +1,7 @@
export function DefaultTag() {
export const DefaultTag = () => {
return (
<div className="flex h-6 items-center justify-center rounded-xl bg-slate-200 px-3">
<p className="text-xs">Default</p>
</div>
);
}
};
@@ -31,8 +31,6 @@ const MATCHERS = [
},
];
export const PlaygroundAutoLinkPlugin: React.FC = () => {
export const PlaygroundAutoLinkPlugin = () => {
return <AutoLinkPlugin matchers={MATCHERS} />;
};
export default PlaygroundAutoLinkPlugin;
+4 -4
View File
@@ -15,9 +15,9 @@ import type { Dispatch, SetStateAction } from "react";
import { cn } from "@formbricks/lib/cn";
import AutoLinkPlugin from "../components/AutoLinkPlugin";
import ToolbarPlugin from "../components/ToolbarPlugin";
import ExampleTheme from "../lib/ExampleTheme";
import { PlaygroundAutoLinkPlugin as AutoLinkPlugin } from "../components/AutoLinkPlugin";
import { ToolbarPlugin } from "../components/ToolbarPlugin";
import { exampleTheme } from "../lib/ExampleTheme";
import "../stylesEditor.css";
import "../stylesEditorFrontend.css";
@@ -43,7 +43,7 @@ export type TextEditorProps = {
};
const editorConfig = {
theme: ExampleTheme,
theme: exampleTheme,
onError(error: any) {
throw error;
},

Some files were not shown because too many files have changed in this diff Show More