mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-26 03:35:38 -05:00
Merge branch 'main' of github.com:formbricks/formbricks into shubham/for-1119-tweak-set-default-for-in-app-surveys-to-limit-to-50
This commit is contained in:
@@ -1,53 +1,76 @@
|
||||
import fbsetup from "../../public/fb-setup.png";
|
||||
import formbricks from "@formbricks/js";
|
||||
import Image from "next/image";
|
||||
import { useEffect, useState } from "react";
|
||||
import fbsetup from "../../public/fb-setup.png";
|
||||
|
||||
export default function AppPage({}) {
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (darkMode) {
|
||||
document.body.classList.add("dark");
|
||||
} else {
|
||||
document.body.classList.remove("dark");
|
||||
}
|
||||
}, [darkMode]);
|
||||
|
||||
return (
|
||||
<div className="px-12 py-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Formbricks In-product Survey Demo App</h1>
|
||||
<p className="text-slate-700">
|
||||
This app helps you test your in-app surveys. You can create an test user actions, create and update
|
||||
user attributes, etc.
|
||||
</p>
|
||||
<div className="h-screen bg-white px-12 py-6 dark:bg-slate-800">
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-white">
|
||||
Formbricks In-product Survey Demo App
|
||||
</h1>
|
||||
<p className="text-slate-700 dark:text-slate-300">
|
||||
This app helps you test your in-app surveys. You can create and test user actions, create and
|
||||
update user attributes, etc.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
className="rounded-lg bg-slate-200 px-6 py-1 dark:bg-slate-700 dark:text-slate-100"
|
||||
onClick={() => setDarkMode(!darkMode)}>
|
||||
Toggle Dark Mode
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="my-4 grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<div>
|
||||
<div className="rounded-lg border border-slate-300 bg-slate-100 p-6">
|
||||
<h3 className="text-lg font-semibold">Setup .env</h3>
|
||||
<p className="text-slate-700">
|
||||
<div className="rounded-lg border border-slate-300 bg-slate-100 p-6 dark:border-slate-600 dark:bg-slate-900">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-white">Setup .env</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300">
|
||||
Copy the environment ID of your Formbricks app to the env variable in demo/.env
|
||||
</p>
|
||||
<Image src={fbsetup} alt="fb setup" className="mt-4 rounded" priority />
|
||||
</div>
|
||||
<div className="mt-4 rounded-lg border border-slate-300 bg-slate-100 p-6">
|
||||
<h3 className="text-lg font-semibold">Widget Logs</h3>
|
||||
<p className="text-slate-700">
|
||||
Look at the logs to understand how the widget works. <strong>Open your browser console</strong>{" "}
|
||||
to see the logs.
|
||||
<div className="mt-4 rounded-lg border border-slate-300 bg-slate-100 p-6 dark:border-slate-600 dark:bg-slate-900">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-white">Widget Logs</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300">
|
||||
Look at the logs to understand how the widget works.{" "}
|
||||
<strong className="dark:text-white">Open your browser console</strong> to see the logs.
|
||||
</p>
|
||||
{/* <div className="max-h-[40vh] overflow-y-auto py-4">
|
||||
{/* <div className="max-h-[40vh] overflow-y-auto py-4">
|
||||
<LogsContainer />
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:grid md:grid-cols-3">
|
||||
<div className="col-span-3 rounded-lg border border-slate-300 bg-slate-100 p-6">
|
||||
<h3 className="text-lg font-semibold">Reset person / pull data from Formbricks app</h3>
|
||||
<p className="text-slate-700">
|
||||
<div className="col-span-3 rounded-lg border border-slate-300 bg-slate-100 p-6 dark:border-gray-600 dark:bg-gray-800">
|
||||
<h3 className="text-lg font-semibold dark:text-white">
|
||||
Reset person / pull data from Formbricks app
|
||||
</h3>
|
||||
<p className="text-slate-700 dark:text-gray-300">
|
||||
On formbricks.logout() a few things happen: <strong>New person is created</strong> and{" "}
|
||||
<strong>surveys & no-code actions are pulled from Formbricks:</strong>.
|
||||
</p>
|
||||
<button
|
||||
className="my-4 rounded-lg bg-slate-500 px-6 py-3 text-white hover:bg-slate-700"
|
||||
className="my-4 rounded-lg bg-slate-500 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600"
|
||||
onClick={() => {
|
||||
formbricks.logout();
|
||||
}}>
|
||||
Logout
|
||||
</button>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
If you made a change in Formbricks app and it does not seem to work, hit 'Logout' and
|
||||
try again.
|
||||
</p>
|
||||
@@ -56,7 +79,7 @@ export default function AppPage({}) {
|
||||
<div className="p-6">
|
||||
<div>
|
||||
<button
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700"
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600"
|
||||
onClick={() => {
|
||||
formbricks.track("Code Action");
|
||||
}}>
|
||||
@@ -64,7 +87,7 @@ export default function AppPage({}) {
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sends a{" "}
|
||||
<a href="https://formbricks.com/docs/actions/code" className="underline" target="_blank">
|
||||
Code Action
|
||||
@@ -75,18 +98,24 @@ export default function AppPage({}) {
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<div>
|
||||
<button className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700">
|
||||
<button className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
|
||||
No-Code Action
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sends a{" "}
|
||||
<a href="https://formbricks.com/docs/actions/no-code" className="underline" target="_blank">
|
||||
<a
|
||||
href="https://formbricks.com/docs/actions/no-code"
|
||||
className="underline dark:text-blue-500"
|
||||
target="_blank">
|
||||
No Code Action
|
||||
</a>{" "}
|
||||
as long as you created it beforehand in the Formbricks App.{" "}
|
||||
<a href="https://formbricks.com/docs/actions/no-code" target="_blank" className="underline">
|
||||
<a
|
||||
href="https://formbricks.com/docs/actions/no-code"
|
||||
target="_blank"
|
||||
className="underline dark:text-blue-500">
|
||||
Here are instructions on how to do it.
|
||||
</a>
|
||||
</p>
|
||||
@@ -98,17 +127,17 @@ export default function AppPage({}) {
|
||||
onClick={() => {
|
||||
formbricks.setAttribute("Plan", "Free");
|
||||
}}
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700">
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
|
||||
Set Plan to 'Free'
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sets the{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/custom-attributes"
|
||||
target="_blank"
|
||||
className="underline">
|
||||
className="underline dark:text-blue-500">
|
||||
attribute
|
||||
</a>{" "}
|
||||
'Plan' to 'Free'. If the attribute does not exist, it creates it.
|
||||
@@ -121,17 +150,17 @@ export default function AppPage({}) {
|
||||
onClick={() => {
|
||||
formbricks.setAttribute("Plan", "Paid");
|
||||
}}
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700">
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
|
||||
Set Plan to 'Paid'
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sets the{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/custom-attributes"
|
||||
target="_blank"
|
||||
className="underline">
|
||||
className="underline dark:text-blue-500">
|
||||
attribute
|
||||
</a>{" "}
|
||||
'Plan' to 'Paid'. If the attribute does not exist, it creates it.
|
||||
@@ -144,17 +173,17 @@ export default function AppPage({}) {
|
||||
onClick={() => {
|
||||
formbricks.setEmail("test@web.com");
|
||||
}}
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700">
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
|
||||
Set Email
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sets the{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/identify-users"
|
||||
target="_blank"
|
||||
className="underline">
|
||||
className="underline dark:text-blue-500">
|
||||
user email
|
||||
</a>{" "}
|
||||
'test@web.com'
|
||||
@@ -167,17 +196,17 @@ export default function AppPage({}) {
|
||||
onClick={() => {
|
||||
formbricks.setUserId("THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING");
|
||||
}}
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700">
|
||||
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
|
||||
Set User ID
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-slate-700">
|
||||
<p className="text-xs text-slate-700 dark:text-gray-300">
|
||||
This button sets an external{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/identify-users"
|
||||
target="_blank"
|
||||
className="underline">
|
||||
className="underline dark:text-blue-500">
|
||||
user ID
|
||||
</a>{" "}
|
||||
to 'THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING'
|
||||
|
||||
@@ -5,6 +5,7 @@ module.exports = {
|
||||
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/shared/DropdownMenu";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@formbricks/ui";
|
||||
import LoadingSpinner from "@/components/shared/LoadingSpinner";
|
||||
import CreateTeamModal from "@/components/team/CreateTeamModal";
|
||||
import {
|
||||
@@ -65,6 +66,8 @@ import AddProductModal from "./AddProductModal";
|
||||
import { formbricksLogout } from "@/lib/formbricks";
|
||||
import formbricks from "@formbricks/js";
|
||||
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
|
||||
import { MenuIcon } from "lucide-react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
|
||||
interface EnvironmentsNavbarProps {
|
||||
environmentId: string;
|
||||
@@ -86,6 +89,8 @@ export default function EnvironmentsNavbar({ environmentId, session }: Environme
|
||||
const [showAddProductModal, setShowAddProductModal] = useState(false);
|
||||
const [showCreateTeamModal, setShowCreateTeamModal] = useState(false);
|
||||
|
||||
const [mobileNavMenuOpen, setMobileNavMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (environment && environment.widgetSetupCompleted) {
|
||||
setWidgetSetupCompleted(true);
|
||||
@@ -227,13 +232,14 @@ export default function EnvironmentsNavbar({ environmentId, session }: Environme
|
||||
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<div className="flex h-14 justify-between">
|
||||
<div className="flex space-x-4 py-2">
|
||||
<div className="flex space-x-4 py-2">
|
||||
<Link
|
||||
href={`/environments/${environmentId}/surveys/`}
|
||||
className=" flex items-center justify-center rounded-md bg-gradient-to-b text-white transition-all ease-in-out hover:scale-105">
|
||||
{/* <PlusIcon className="h-6 w-6" /> */}
|
||||
<Image src={FaveIcon} width={30} height={30} alt="faveicon" />
|
||||
</Link>
|
||||
|
||||
{navigation.map((item) => {
|
||||
const IconComponent: React.ElementType = item.icon;
|
||||
|
||||
@@ -245,7 +251,7 @@ export default function EnvironmentsNavbar({ environmentId, session }: Environme
|
||||
item.current
|
||||
? "bg-slate-100 text-slate-900"
|
||||
: "text-slate-900 hover:bg-slate-50 hover:text-slate-900",
|
||||
"inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
|
||||
"hidden items-center rounded-md px-2 py-1 text-sm font-medium sm:inline-flex"
|
||||
)}
|
||||
aria-current={item.current ? "page" : undefined}>
|
||||
<IconComponent className="mr-3 h-5 w-5" />
|
||||
@@ -254,6 +260,34 @@ export default function EnvironmentsNavbar({ environmentId, session }: Environme
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center sm:hidden">
|
||||
<Popover open={mobileNavMenuOpen} onOpenChange={setMobileNavMenuOpen}>
|
||||
<PopoverTrigger onClick={() => setMobileNavMenuOpen(!mobileNavMenuOpen)}>
|
||||
<span>
|
||||
<MenuIcon className="h-6 w-6 rounded-md bg-slate-200 p-1 text-slate-600" />
|
||||
</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="mr-4 bg-slate-200">
|
||||
<div className="flex flex-col">
|
||||
{navigation.map((navItem) => (
|
||||
<Link key={navItem.name} href={navItem.href}>
|
||||
<div
|
||||
onClick={() => setMobileNavMenuOpen(false)}
|
||||
className={cn(
|
||||
"flex items-center space-x-2 rounded-md p-2",
|
||||
navItem.current && "bg-slate-300"
|
||||
)}>
|
||||
<navItem.icon className="h-5 w-5" />
|
||||
<span className="font-medium text-slate-600">{navItem.name}</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<div className="hidden sm:ml-6 sm:flex sm:items-center">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use server";
|
||||
|
||||
import { updateProfile, deleteProfile } from "@formbricks/lib/services/profile";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { TProfileUpdateInput } from "@formbricks/types/v1/profile";
|
||||
|
||||
export async function profileEditAction(userId: string, data: Prisma.UserUpdateInput) {
|
||||
export async function profileEditAction(userId: string, data: Partial<TProfileUpdateInput>) {
|
||||
return await updateProfile(userId, data);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -14,6 +14,7 @@ interface LinkSurveyShareButtonProps {
|
||||
|
||||
export default function LinkSurveyShareButton({ survey, className }: LinkSurveyShareButtonProps) {
|
||||
const [showLinkModal, setShowLinkModal] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
|
||||
+22
-11
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import CodeBlock from "@/components/shared/CodeBlock";
|
||||
import Modal from "@/components/shared/Modal";
|
||||
// import Modal from "@/components/shared/Modal";
|
||||
import { Dialog, DialogContent } from "@formbricks/ui";
|
||||
import { TSurvey } from "@formbricks/types/v1/surveys";
|
||||
import { Button } from "@formbricks/ui";
|
||||
import { CheckIcon } from "@heroicons/react/24/outline";
|
||||
@@ -40,8 +41,8 @@ top:0; width:100%; height:100%; border:0;">
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal open={open} setOpen={setOpen} blur={false}>
|
||||
<div>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className="bottom-0 max-w-sm bg-white p-4 sm:bottom-auto sm:max-w-xl sm:p-6">
|
||||
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-teal-100">
|
||||
<CheckIcon className="h-6 w-6 text-teal-600" aria-hidden="true" />
|
||||
</div>
|
||||
@@ -50,24 +51,32 @@ top:0; width:100%; height:100%; border:0;">
|
||||
{showEmbed ? (
|
||||
<div className="mt-4">
|
||||
<p className="text-sm text-gray-500">Embed survey on your website:</p>
|
||||
<CodeBlock language="html">{iframeCode}</CodeBlock>
|
||||
<CodeBlock
|
||||
customCodeClass="!whitespace-normal sm:!whitespace-pre-wrap !break-all sm:!break-normal"
|
||||
language="html">
|
||||
{iframeCode}
|
||||
</CodeBlock>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-4">
|
||||
<p className="text-sm text-gray-500">Share this link to let people answer your survey:</p>
|
||||
<p
|
||||
<div
|
||||
ref={linkTextRef}
|
||||
className="relative mt-3 w-full rounded-lg border border-slate-300 bg-slate-50 p-3 text-center text-slate-800"
|
||||
className="relative mt-3 max-w-full overflow-auto rounded-lg border border-slate-300 bg-slate-50 p-3 text-center text-slate-800"
|
||||
onClick={() => handleTextSelection()}>
|
||||
{`${window.location.protocol}//${window.location.host}/s/${survey.id}`}
|
||||
</p>
|
||||
<span
|
||||
style={{
|
||||
wordBreak: "break-all",
|
||||
}}>{`${window.location.protocol}//${window.location.host}/s/${survey.id}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-4 flex justify-end space-x-2">
|
||||
<div className="mt-4 flex flex-col justify-center gap-2 sm:flex-row sm:justify-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
title="Embed survey in your website"
|
||||
aria-label="Embed survey in your website"
|
||||
className="flex justify-center"
|
||||
onClick={() => {
|
||||
setShowEmbed(true);
|
||||
navigator.clipboard.writeText(iframeCode);
|
||||
@@ -87,6 +96,7 @@ top:0; width:100%; height:100%; border:0;">
|
||||
}}
|
||||
title="Copy survey link to clipboard"
|
||||
aria-label="Copy survey link to clipboard"
|
||||
className="flex justify-center"
|
||||
EndIcon={DocumentDuplicateIcon}>
|
||||
Copy URL
|
||||
</Button>
|
||||
@@ -94,6 +104,7 @@ top:0; width:100%; height:100%; border:0;">
|
||||
variant="darkCTA"
|
||||
title="Preview survey"
|
||||
aria-label="Preview survey"
|
||||
className="flex justify-center"
|
||||
href={`${window.location.protocol}//${window.location.host}/s/${survey.id}?preview=true`}
|
||||
target="_blank"
|
||||
EndIcon={EyeIcon}>
|
||||
@@ -101,7 +112,7 @@ top:0; width:100%; height:100%; border:0;">
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import CustomFilter from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/CustomFilter";
|
||||
import SummaryHeader from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/SummaryHeader";
|
||||
import SurveyResultsTabs from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/SurveyResultsTabs";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { DocumentDuplicateIcon } from "@heroicons/react/24/outline";
|
||||
import Prism from "prismjs";
|
||||
import "prismjs/themes/prism.css";
|
||||
@@ -9,15 +10,16 @@ import toast from "react-hot-toast";
|
||||
interface CodeBlockProps {
|
||||
children: React.ReactNode;
|
||||
language: string;
|
||||
customCodeClass?: string;
|
||||
}
|
||||
|
||||
const CodeBlock: React.FC<CodeBlockProps> = ({ children, language }) => {
|
||||
const CodeBlock: React.FC<CodeBlockProps> = ({ children, language, customCodeClass = "" }) => {
|
||||
useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
}, [children]);
|
||||
|
||||
return (
|
||||
<div className="group relative mt-4 rounded-md text-sm text-slate-200">
|
||||
<div className="group relative mt-4 rounded-md text-sm text-slate-200">
|
||||
<DocumentDuplicateIcon
|
||||
className="absolute right-4 top-4 z-20 h-5 w-5 cursor-pointer text-slate-600 opacity-0 transition-all duration-150 group-hover:opacity-60"
|
||||
onClick={() => {
|
||||
@@ -27,7 +29,7 @@ const CodeBlock: React.FC<CodeBlockProps> = ({ children, language }) => {
|
||||
}}
|
||||
/>
|
||||
<pre>
|
||||
<code className={`language-${language} whitespace-pre-wrap`}>{children}</code>
|
||||
<code className={cn(`language-${language} whitespace-pre-wrap`, customCodeClass)}>{children}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -241,6 +241,7 @@ export const useLinkSurveyUtils = (survey: Survey) => {
|
||||
const nextQuestionId = getNextQuestionId(answer);
|
||||
|
||||
if (nextQuestionId === "end") {
|
||||
setLoadingElement(false);
|
||||
setProgress(1);
|
||||
setFinished(true);
|
||||
clearStoredResponses(survey.id);
|
||||
|
||||
@@ -59,7 +59,7 @@ export default function ConsentQuestion({
|
||||
e.preventDefault();
|
||||
handleSumbit(answer);
|
||||
}}>
|
||||
<label className="fb-relative fb-z-10 fb-mt-4 fb-flex fb-w-full fb-cursor-pointer fb-items-center fb-rounded-md fb-border fb-border-gray-200 fb-bg-slate-50 fb-p-4 fb-text-sm focus:fb-outline-none">
|
||||
<label className="fb-relative fb-z-10 fb-mt-4 fb-flex fb-w-full fb-cursor-pointer fb-items-center fb-rounded-md fb-border fb-border-gray-200 fb-bg-slate-50 fb-p-4 fb-text-sm focus:fb-outline-none fb-text-slate-800">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={question.id}
|
||||
|
||||
@@ -126,7 +126,7 @@ export default function MultipleChoiceMultiQuestion({
|
||||
selectedChoices.includes(choice.label)
|
||||
? "fb-z-10 fb-border-slate-400 fb-bg-slate-50"
|
||||
: "fb-border-gray-200",
|
||||
"fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-space-y-3 fb-rounded-md fb-border fb-p-4 hover:fb-bg-slate-50 focus:fb-outline-none"
|
||||
"fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-space-y-3 fb-rounded-md fb-border fb-p-4 hover:fb-bg-slate-50 focus:fb-outline-none fb-text-slate-800"
|
||||
)}>
|
||||
<span className="fb-flex fb-items-center fb-text-sm">
|
||||
<input
|
||||
|
||||
@@ -109,7 +109,7 @@ export default function MultipleChoiceSingleQuestion({
|
||||
selectedChoice === choice.label
|
||||
? "fb-z-10 fb-bg-slate-50 fb-border-slate-400"
|
||||
: "fb-border-gray-200",
|
||||
"fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-rounded-md fb-border fb-p-4 focus:fb-outline-none hover:bg-slate-50"
|
||||
"fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-rounded-md fb-border fb-p-4 focus:fb-outline-none hover:bg-slate-50 fb-text-slate-800"
|
||||
)}>
|
||||
<span className="fb-flex fb-items-center fb-text-sm">
|
||||
<input
|
||||
|
||||
@@ -72,7 +72,7 @@ export default function NPSQuestion({
|
||||
key={number}
|
||||
className={cn(
|
||||
selectedChoice === number ? "fb-z-10 fb-border-slate-400 fb-bg-slate-50" : "",
|
||||
"fb-relative fb-h-10 fb-flex-1 fb-cursor-pointer fb-border fb-bg-white fb-text-center fb-text-sm fb-leading-10 first:fb-rounded-l-md last:fb-rounded-r-md hover:fb-bg-gray-100 focus:fb-outline-none"
|
||||
"fb-relative fb-h-10 fb-flex-1 fb-cursor-pointer fb-border fb-bg-white fb-text-center fb-text-sm fb-leading-10 first:fb-rounded-l-md last:fb-rounded-r-md hover:fb-bg-gray-100 focus:fb-outline-none fb-text-slate-800"
|
||||
)}>
|
||||
<input
|
||||
type="radio"
|
||||
|
||||
@@ -105,7 +105,7 @@ export default function RatingQuestion({
|
||||
selectedChoice === number ? "fb-z-10 fb-border-slate-400 fb-bg-slate-50" : "",
|
||||
a.length === number ? "fb-rounded-r-md" : "",
|
||||
number === 1 ? "fb-rounded-l-md" : "",
|
||||
"fb-block fb-h-full fb-w-full fb-border hover:fb-bg-gray-100 focus:fb-outline-none"
|
||||
"fb-block fb-h-full fb-w-full fb-border hover:fb-bg-gray-100 focus:fb-outline-none fb-text-slate-800"
|
||||
)}>
|
||||
<HiddenRadioInput number={number} />
|
||||
{number}
|
||||
@@ -148,7 +148,7 @@ export default function RatingQuestion({
|
||||
)}
|
||||
</label>
|
||||
) : (
|
||||
<label className="fb-flex fb-h-full fb-w-full fb-justify-center">
|
||||
<label className="fb-flex fb-h-full fb-w-full fb-justify-center fb-text-slate-800">
|
||||
<HiddenRadioInput number={number} />
|
||||
<RatingSmiley
|
||||
active={selectedChoice == number || hoveredNumber == number}
|
||||
@@ -160,7 +160,7 @@ export default function RatingQuestion({
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="fb-flex fb-justify-between fb-text-slate-500 fb-leading-6 fb-px-1.5 fb-text-xs">
|
||||
<div className="fb-flex fb-justify-between fb-text-slate-500 fb-leading-6 fb-px-1.5 fb-text-xs">
|
||||
<p>{question.lowerLabel}</p>
|
||||
<p>{question.upperLabel}</p>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,17 @@ import z from "zod";
|
||||
|
||||
export const ZProfile = z.object({
|
||||
id: z.string(),
|
||||
name: z.string().nullish(),
|
||||
name: z.string().nullable(),
|
||||
email: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
});
|
||||
|
||||
export type TProfile = z.infer<typeof ZProfile>;
|
||||
|
||||
export const ZProfileUpdateInput = z.object({
|
||||
name: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
});
|
||||
|
||||
export type TProfileUpdateInput = z.infer<typeof ZProfileUpdateInput>;
|
||||
|
||||
+39
-47
@@ -1,51 +1,12 @@
|
||||
export { PersonAvatar, ProfileAvatar } from "./components/Avatars";
|
||||
export { Alert, AlertDescription, AlertTitle } from "./components/Alert";
|
||||
export { PersonAvatar, ProfileAvatar } from "./components/Avatars";
|
||||
export { Badge } from "./components/Badge";
|
||||
export { Button } from "./components/Button";
|
||||
export { Calendar } from "./components/Calendar";
|
||||
export { Card } from "./components/Card";
|
||||
export type { CardProps } from "./components/Card";
|
||||
export { Checkbox } from "./components/Checkbox";
|
||||
export { ColorPicker } from "./components/ColorPicker";
|
||||
export { Confetti } from "./components/Confetti";
|
||||
export {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuShortcut,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuRadioGroup,
|
||||
} from "./components/DropdownMenu";
|
||||
export { Editor, AddVariablesDropdown } from "./components/editor";
|
||||
export { ErrorComponent } from "./components/ErrorComponent";
|
||||
export { Input } from "./components/Input";
|
||||
export { PasswordInput } from "./components/PasswordInput";
|
||||
export { Label } from "./components/Label";
|
||||
export { Popover, PopoverTrigger, PopoverContent } from "./components/Popover";
|
||||
export { ProgressBar, HalfCircle } from "./components/ProgressBar";
|
||||
export { RadioGroup, RadioGroupItem } from "./components/RadioGroup";
|
||||
export { ResponsiveVideo } from "./components/ResponsiveVideo";
|
||||
export {
|
||||
Select,
|
||||
SelectGroup,
|
||||
SelectValue,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectLabel,
|
||||
SelectItem,
|
||||
SelectSeparator,
|
||||
} from "./components/Select";
|
||||
export { Switch } from "./components/Switch";
|
||||
export { TabBar } from "./components/TabBar";
|
||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "./components/Tooltip";
|
||||
export {
|
||||
Command,
|
||||
CommandDialog,
|
||||
@@ -55,15 +16,45 @@ export {
|
||||
CommandItem,
|
||||
CommandList,
|
||||
CommandSeparator,
|
||||
CommandShortcut,
|
||||
CommandShortcut
|
||||
} from "./components/Command";
|
||||
export { Calendar } from "./components/Calendar";
|
||||
export { Confetti } from "./components/Confetti";
|
||||
export { DatePicker } from "./components/DatePicker";
|
||||
export {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger
|
||||
} from "./components/Dialog";
|
||||
export {
|
||||
DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator,
|
||||
DropdownMenuShortcut, DropdownMenuSub,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger, DropdownMenuTrigger
|
||||
} from "./components/DropdownMenu";
|
||||
export { ErrorComponent } from "./components/ErrorComponent";
|
||||
export { Input } from "./components/Input";
|
||||
export { Label } from "./components/Label";
|
||||
export { PasswordInput } from "./components/PasswordInput";
|
||||
export { Popover, PopoverContent, PopoverTrigger } from "./components/Popover";
|
||||
export { HalfCircle, ProgressBar } from "./components/ProgressBar";
|
||||
export { RadioGroup, RadioGroupItem } from "./components/RadioGroup";
|
||||
export { ResponsiveVideo } from "./components/ResponsiveVideo";
|
||||
export { SearchBox } from "./components/SearchBox";
|
||||
export {
|
||||
Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue
|
||||
} from "./components/Select";
|
||||
export { Switch } from "./components/Switch";
|
||||
export { TabBar } from "./components/TabBar";
|
||||
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/Tooltip";
|
||||
export { AddVariablesDropdown, Editor } from "./components/editor";
|
||||
|
||||
/* Icons */
|
||||
export { AngryBirdRageIcon } from "./components/icons/AngryBirdRageIcon";
|
||||
export { AngryBirdRage2Icon } from "./components/icons/AngryBirdRage2Icon";
|
||||
export { AngryBirdRageIcon } from "./components/icons/AngryBirdRageIcon";
|
||||
export { AppPieChartIcon } from "./components/icons/AppPieChartIcon";
|
||||
export { ArchiveIcon } from "./components/icons/ArchiveIcon";
|
||||
export { ArrowRightCircleIcon } from "./components/icons/ArrowRightCircleIcon";
|
||||
@@ -72,8 +63,8 @@ export { BackIcon } from "./components/icons/BackIcon";
|
||||
export { BaseballIcon } from "./components/icons/BaseballIcon";
|
||||
export { BellIcon } from "./components/icons/BellIcon";
|
||||
export { BrainIcon } from "./components/icons/BrainIcon";
|
||||
export { BugIcon } from "./components/icons/BugIcon";
|
||||
export { BugBlueIcon } from "./components/icons/BugBlueIcon";
|
||||
export { BugIcon } from "./components/icons/BugIcon";
|
||||
export { CancelSubscriptionIcon } from "./components/icons/CancelSubscriptionIcon";
|
||||
export { CashCalculatorIcon } from "./components/icons/CashCalculatorIcon";
|
||||
export { CheckMarkIcon } from "./components/icons/CheckMarkIcon";
|
||||
@@ -92,14 +83,15 @@ export { EyeIcon } from "./components/icons/EyeIcon";
|
||||
export { FeatureRequestIcon } from "./components/icons/FeatureRequestIcon";
|
||||
export { FeedbackIcon } from "./components/icons/FeedbackIcon";
|
||||
export { FilterIcon } from "./components/icons/FilterIcon";
|
||||
export { FounderIcon } from "./components/icons/FounderIcon";
|
||||
export { FormIcon } from "./components/icons/FormIcon";
|
||||
export { FounderIcon } from "./components/icons/FounderIcon";
|
||||
export { GaugeSpeedFastIcon } from "./components/icons/GaugeSpeedFastIcon";
|
||||
export { HandPuzzleIcon } from "./components/icons/HandPuzzleIcon";
|
||||
export { HeartCommentIcon } from "./components/icons/HeartCommentIcon";
|
||||
export { InterviewPromptIcon } from "./components/icons/InterviewPromptIcon";
|
||||
export { LaptopWorkerIcon } from "./components/icons/LaptopWorkerIcon";
|
||||
export { LoadingBarIcon } from "./components/icons/LoadingBarIcon";
|
||||
export { NetPromoterScoreIcon } from "./components/icons/NetPromoterScoreIcon";
|
||||
export { NotDisappointedIcon } from "./components/icons/NotDisappointedIcon";
|
||||
export { OnboardingIcon } from "./components/icons/OnboardingIcon";
|
||||
export { PMFIcon } from "./components/icons/PMFIcon";
|
||||
@@ -115,4 +107,4 @@ export { UserGroupIcon } from "./components/icons/UserGroupIcon";
|
||||
export { UserSearchGlasIcon } from "./components/icons/UserSearchGlasIcon";
|
||||
export { VeryDisappointedIcon } from "./components/icons/VeryDisappointedIcon";
|
||||
export { VideoTabletAdjustIcon } from "./components/icons/VideoTabletAdjustIcon";
|
||||
export { NetPromoterScoreIcon } from "./components/icons/NetPromoterScoreIcon";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user