feat: add prolific info and docs page (#2853)

This commit is contained in:
Johannes
2024-07-08 15:21:24 +05:30
committed by GitHub
parent 71f661daa4
commit b8fa581665
19 changed files with 362 additions and 79 deletions
@@ -1,18 +1,16 @@
"use client";
import { ArrowLeftIcon, BellRing, BlocksIcon, Code2Icon, LinkIcon, MailIcon } from "lucide-react";
import { BellRing, BlocksIcon, Code2Icon, LinkIcon, MailIcon, UsersRound } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { cn } from "@formbricks/lib/cn";
import { TSurvey } from "@formbricks/types/surveys";
import { TUser } from "@formbricks/types/user";
import { Button } from "@formbricks/ui/Button";
import { Badge } from "@formbricks/ui/Badge";
import { Dialog, DialogContent } from "@formbricks/ui/Dialog";
import { ShareSurveyLink } from "@formbricks/ui/ShareSurveyLink";
import { EmailTab } from "./shareEmbedTabs/EmailTab";
import { LinkTab } from "./shareEmbedTabs/LinkTab";
import { WebpageTab } from "./shareEmbedTabs/WebpageTab";
import { EmbedView } from "./shareEmbedModal/EmbedView";
import { PanelInfoView } from "./shareEmbedModal/PanelInfoView";
interface ShareEmbedSurveyProps {
survey: TSurvey;
@@ -21,6 +19,7 @@ interface ShareEmbedSurveyProps {
webAppUrl: string;
user: TUser;
}
export const ShareEmbedSurvey = ({ survey, open, setOpen, webAppUrl, user }: ShareEmbedSurveyProps) => {
const router = useRouter();
const environmentId = survey.environmentId;
@@ -34,26 +33,26 @@ export const ShareEmbedSurvey = ({ survey, open, setOpen, webAppUrl, user }: Sha
];
const [activeId, setActiveId] = useState(tabs[0].id);
const [showInitialPage, setShowInitialPage] = useState(true);
const [showView, setShowView] = useState("start");
const [surveyUrl, setSurveyUrl] = useState("");
const handleOpenChange = (open: boolean) => {
setActiveId(tabs[0].id);
setOpen(open);
setShowInitialPage(open); // Reset to initial page when modal opens
setShowView(open ? "start" : ""); // Reset to initial page when modal opens or closes
// fetch latest responses
router.refresh();
};
const handleInitialPageButton = () => {
setShowInitialPage(!showInitialPage);
setShowView("start");
};
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent className="w-full max-w-xl bg-white p-0 md:max-w-3xl lg:h-[700px] lg:max-w-5xl">
{showInitialPage ? (
{showView === "start" ? (
<div className="h-full max-w-full overflow-hidden">
<div className="flex h-[200px] w-full flex-col items-center justify-center space-y-6 p-8 text-center lg:h-2/5">
<p className="pt-2 text-xl font-semibold text-slate-800">Your survey is public 🎉</p>
@@ -66,10 +65,10 @@ export const ShareEmbedSurvey = ({ survey, open, setOpen, webAppUrl, user }: Sha
</div>
<div className="flex h-[300px] flex-col items-center justify-center gap-8 rounded-b-lg bg-slate-50 px-8 lg:h-3/5">
<p className="-mt-8 text-sm text-slate-500">What&apos;s next?</p>
<div className="grid grid-cols-3 gap-2">
<div className="grid grid-cols-4 gap-2">
<button
type="button"
onClick={handleInitialPageButton}
onClick={() => setShowView("embed")}
className="flex flex-col items-center gap-3 rounded-lg border border-slate-100 bg-white p-4 text-sm text-slate-500 hover:border-slate-200 md:p-8">
<Code2Icon className="h-6 w-6 text-slate-700" />
Embed survey
@@ -86,76 +85,32 @@ export const ShareEmbedSurvey = ({ survey, open, setOpen, webAppUrl, user }: Sha
<BlocksIcon className="h-6 w-6 text-slate-700" />
Setup integrations
</Link>
<button
type="button"
onClick={() => setShowView("panel")}
className="relative flex flex-col items-center gap-3 rounded-lg border border-slate-100 bg-white p-4 text-sm text-slate-500 hover:border-slate-200 md:p-8">
<UsersRound className="h-6 w-6 text-slate-700" />
Send to panel
<Badge size="tiny" type="success" text="New" className="absolute right-3 top-3" />
</button>
</div>
</div>
</div>
) : (
<div className="h-full overflow-hidden">
<div className="border-b border-slate-200 py-2">
<Button
variant="minimal"
className="focus:ring-0"
onClick={handleInitialPageButton}
StartIcon={ArrowLeftIcon}>
Back
</Button>
</div>
<div className="grid h-full grid-cols-4">
<div className="col-span-1 hidden flex-col gap-3 border-r border-slate-200 p-4 lg:flex">
{tabs.map((tab) => (
<Button
StartIcon={tab.icon}
startIconClassName="h-4 w-4"
variant="minimal"
key={tab.id}
onClick={() => setActiveId(tab.id)}
className={cn(
"rounded-md border px-4 py-2 text-slate-600",
// "focus:ring-0 focus:ring-offset-0", // enable these classes to remove the focus rings on buttons
tab.id === activeId
? "border-slate-200 bg-slate-100 font-semibold text-slate-900"
: "border-transparent text-slate-500 hover:text-slate-700"
)}
aria-current={tab.id === activeId ? "page" : undefined}>
{tab.label}
</Button>
))}
</div>
<div className="col-span-4 h-full overflow-y-auto bg-slate-50 px-4 py-6 lg:col-span-3 lg:p-6">
<div>
{activeId === "email" ? (
<EmailTab surveyId={survey.id} email={email} />
) : activeId === "webpage" ? (
<WebpageTab surveyUrl={surveyUrl} />
) : activeId === "link" ? (
<LinkTab
survey={survey}
webAppUrl={webAppUrl}
surveyUrl={surveyUrl}
setSurveyUrl={setSurveyUrl}
/>
) : null}
</div>
<div className="mt-2 rounded-md p-3 text-center lg:hidden">
{tabs.slice(0, 2).map((tab) => (
<Button
variant="minimal"
key={tab.id}
onClick={() => setActiveId(tab.id)}
className={cn(
"rounded-md px-4 py-2",
tab.id === activeId
? "bg-white text-slate-900 shadow-sm"
: "border-transparent text-slate-700 hover:text-slate-900"
)}>
{tab.label}
</Button>
))}
</div>
</div>
</div>
</div>
)}
) : showView === "embed" ? (
<EmbedView
handleInitialPageButton={handleInitialPageButton}
tabs={tabs}
activeId={activeId}
setActiveId={setActiveId}
survey={survey}
email={email}
surveyUrl={surveyUrl}
setSurveyUrl={setSurveyUrl}
webAppUrl={webAppUrl}
/>
) : showView === "panel" ? (
<PanelInfoView handleInitialPageButton={handleInitialPageButton} />
) : null}
</DialogContent>
</Dialog>
);
@@ -0,0 +1,100 @@
"use client";
import { ArrowLeftIcon } from "lucide-react";
import { cn } from "@formbricks/lib/cn";
import { Button } from "@formbricks/ui/Button";
import { EmailTab } from "./EmailTab";
import { LinkTab } from "./LinkTab";
import { WebpageTab } from "./WebpageTab";
interface EmbedViewProps {
handleInitialPageButton: () => void;
tabs: Array<{ id: string; label: string; icon: any }>;
activeId: string;
setActiveId: React.Dispatch<React.SetStateAction<string>>;
survey: any;
email: string;
surveyUrl: string;
setSurveyUrl: React.Dispatch<React.SetStateAction<string>>;
webAppUrl: string;
}
export const EmbedView = ({
handleInitialPageButton,
tabs,
activeId,
setActiveId,
survey,
email,
surveyUrl,
setSurveyUrl,
webAppUrl,
}: EmbedViewProps) => {
return (
<div className="h-full overflow-hidden">
<div className="border-b border-slate-200 py-2">
<Button
variant="minimal"
className="focus:ring-0"
onClick={handleInitialPageButton}
StartIcon={ArrowLeftIcon}>
Back
</Button>
</div>
<div className="grid h-full grid-cols-4">
<div className="col-span-1 hidden flex-col gap-3 border-r border-slate-200 p-4 lg:flex">
{tabs.map((tab) => (
<Button
StartIcon={tab.icon}
startIconClassName="h-4 w-4"
variant="minimal"
key={tab.id}
onClick={() => setActiveId(tab.id)}
className={cn(
"rounded-md border px-4 py-2 text-slate-600",
// "focus:ring-0 focus:ring-offset-0", // enable these classes to remove the focus rings on buttons
tab.id === activeId
? "border-slate-200 bg-slate-100 font-semibold text-slate-900"
: "border-transparent text-slate-500 hover:text-slate-700"
)}
aria-current={tab.id === activeId ? "page" : undefined}>
{tab.label}
</Button>
))}
</div>
<div className="col-span-4 h-full overflow-y-auto bg-slate-50 px-4 py-6 lg:col-span-3 lg:p-6">
<div>
{activeId === "email" ? (
<EmailTab surveyId={survey.id} email={email} />
) : activeId === "webpage" ? (
<WebpageTab surveyUrl={surveyUrl} />
) : activeId === "link" ? (
<LinkTab
survey={survey}
webAppUrl={webAppUrl}
surveyUrl={surveyUrl}
setSurveyUrl={setSurveyUrl}
/>
) : null}
</div>
<div className="mt-2 rounded-md p-3 text-center lg:hidden">
{tabs.slice(0, 2).map((tab) => (
<Button
variant="minimal"
key={tab.id}
onClick={() => setActiveId(tab.id)}
className={cn(
"rounded-md px-4 py-2",
tab.id === activeId
? "bg-white text-slate-900 shadow-sm"
: "border-transparent text-slate-700 hover:text-slate-900"
)}>
{tab.label}
</Button>
))}
</div>
</div>
</div>
</div>
);
};
@@ -0,0 +1,96 @@
"use client";
import ProlificLogo from "@/images/prolific-logo.webp";
import ProlificUI from "@/images/prolific-screenshot.webp";
import { ArrowLeftIcon } from "lucide-react";
import Image from "next/image";
import { Button } from "@formbricks/ui/Button";
interface PanelInfoViewProps {
handleInitialPageButton: () => void;
}
export const PanelInfoView = ({ handleInitialPageButton }: PanelInfoViewProps) => {
return (
<div className="h-full overflow-hidden text-slate-900">
<div className="border-b border-slate-200 py-2">
<Button
variant="minimal"
className="focus:ring-0"
onClick={handleInitialPageButton}
StartIcon={ArrowLeftIcon}>
Back
</Button>
</div>
<div className="grid h-full grid-cols-2">
<div className="flex flex-col gap-y-6 border-r border-slate-200 p-8">
<Image src={ProlificUI} alt="Prolific panel selection UI" className="rounded-lg shadow-lg" />
<div>
<p className="text-md font-semibold">What is a panel?</p>
<p className="text-slate-600">
A panel is a group of participants selected based on characteristics such as age, profession,
gender, etc.
</p>
</div>
<div>
<p className="text-md font-semibold">When do I need it?</p>
<p className="text-slate-600">
If you dont have access to enough people who match your target audience, it makes sense to pay
for access to a panel.
</p>
</div>
<div>
<p className="text-md font-semibold">What is Prolific?</p>
<p className="text-slate-600">
Were partnering with Prolific to offer you access to a pool of 200.000 participant to do
research with.
</p>
</div>
</div>
<div className="relative flex flex-col gap-y-6 bg-slate-50 p-8">
<Image
src={ProlificLogo}
alt="Prolific panel selection UI"
className="absolute right-8 top-8 w-32"
/>
<div>
<h3 className="text-xl font-semibold">How to create a panel</h3>
</div>
<div>
<p className="text-md font-semibold">Step 1: Create an account with Prolific</p>
<p className="text-slate-600">
We partner with Prolific to give you access to a pool of over 200.000 vetted participants.
</p>
</div>
<div>
<p className="text-md font-semibold">Step 2: Create a study</p>
<p className="text-slate-600">
At Prolific, you create a new study where you can pick your preferred audience based on hundreds
of characteristics.
</p>
</div>
<div>
<p className="text-md font-semibold">Step 3: Connect your survey</p>
<p className="text-slate-600">
Set up hidden fields in your Formbricks survey to track which participant provided which answer.
</p>
</div>
<div>
<p className="text-md font-semibold">Step 4: Launch your study</p>
<p className="text-slate-600">
Once everything is setup, you can launch your study. Within a few hours youll receive the first
responses.
</p>
</div>
<Button
variant="darkCTA"
className="justify-center"
href="https://formbricks.com/docs/link-surveys/market-research-panel"
target="_blank">
Get started
</Button>
</div>
</div>
</div>
);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB