mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-08 06:41:45 -05:00
chore: Replace default exports/imports with module exports (#2617)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -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) => {
|
||||
|
||||
+2
-2
@@ -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) => {
|
||||
|
||||
+2
-2
@@ -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) => {
|
||||
|
||||
+2
-2
@@ -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) => {
|
||||
|
||||
+2
-2
@@ -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
-2
@@ -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) => {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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,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
@@ -7,7 +7,7 @@
|
||||
e.parentNode.insertBefore(t, e),
|
||||
setTimeout(function () {
|
||||
formbricks.init({
|
||||
environmentId: "clvzbzhhi000d10cpk0vtopz4",
|
||||
environmentId: "clw6ehzd5008zrx0nmrix2pnw",
|
||||
apiHost: "http://localhost:3000",
|
||||
});
|
||||
}, 500);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() !== "");
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -94,5 +94,3 @@ export class SurveyState {
|
||||
this.responseAcc = { finished: false, data: {}, ttc: {} };
|
||||
}
|
||||
}
|
||||
|
||||
export default SurveyState;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user