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

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,131 @@
import { MdxImage } from "@/components/MdxImage";
import CopySurveyLink from "./copy-survey-link.webp";
import CreateStudy from "./create-study.webp";
import HiddenFields from "./hidden-fields.webp";
import PreviewComplete from "./preview-complete.webp";
import PreviewStudy from "./preview-study.webp";
import AddRedirectUrl from "./redirect-url-formbricks.webp";
import RedirectUrl from "./redirect-url.webp";
import ScreeningOut from "./screening-out.webp";
import UrlParameters from "./url-parameters.webp";
export const metadata = {
title: "Creating a Research Panel with Prolific",
description:
"Formbricks surveys can be integrated with Prolifics participant panel easily. This tutorial walks you through the steps on how to access a pool of over 200.000 participants for your research.",
};
#### Research Panel
# Creating a Research Panel with Prolific
You need a lot of research participants that match your target audience fast?
Formbricks integrates well with Prolific. Prolific provides a pool of over 200.000 research participants you can choose from. Run market research with Formbricks within hours, not days.
<Note>
Prolific is a paid service. You need to fund your account to access the pool of participants. The cost depends on the number of participants you want to reach and the demographics you're targeting. You can get an estimate of the cost with the [Prolific price calculator](https://www.prolific.com/calculator)
</Note>
## Purpose
External research panels are useful when:
- You don't have access to enough people who match your target audience
- You want to reach a specific demographic
- You want to reach a large number of people quickly
## Steps to Follow
### Step 1: Add hidden fields to the Formbricks survey
To be able to attribute a completed answer to a research participant, you need to add hidden fields to your Formbricks survey. To do so, edit your survey and scroll down to the Hidden Fields card.
Add three fields with the IDs `PROLIFIC_PID`, `STUDY_ID`, and `SESSION_ID`.
<MdxImage
src={HiddenFields}
alt="Hidden fields added"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 2: Create an account on Prolific
Go to [Prolific](https://app.prolific.co/) and create an account.
### Step 3: Create a study on Prolific
Once you're logged in to Prolific, create a new study.
<MdxImage
src={CreateStudy}
alt="Create a study on Prolific"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 4: Copy the Formbricks survey link to the Prolific study
We connect the Formbricks survey with the Prolific study by copying the survey link from Formbricks and pasting it into the Prolific study:
<MdxImage
src={CopySurveyLink}
alt="Copy the survey link"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 5: Choose URL parameters for attribution
To attribute responses to the correct participant, you need to add URL parameters to the Formbricks survey link. The parameters are `PROLIFIC_PID`, `STUDY_ID`, and `SESSION_ID`, exactly like the hidden fields you added.
<MdxImage
src={UrlParameters}
alt="Adding URL parameters to the survey"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 6: Update the Formbricks Redirect URL
To ensure that participants are redirected back to Prolific after completing the survey, add the redirect URL provided in the Prolific study setup (e.g. `https://app.prolific.co/submissions/complete?cc=I2PWSFRG`)
Copy from Prolific:
<MdxImage
src={RedirectUrl}
alt="Copy redirect URL"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
Set it up as Redirect URL in the Response Options in Formbricks:
<MdxImage
src={AddRedirectUrl}
alt="Add redirect URL to Formbricks"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 7: Preview the study
Preview the study using Prolific's [Preview-functionality](https://researcher-help.prolific.com/hc/en-gb/articles/360009222853-Previewing-your-study)
<MdxImage
src={PreviewStudy}
alt="Preview study"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
Got to the success screen? Then you're ready to publish your study!
<MdxImage
src={PreviewComplete}
alt="Preview complete"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Step 8: Publish the study
After you've published the study, you'll get the first responses within a few hours.
<Note>
Prolific is a paid service. You need to fund your account to publish your study.
</Note>
### That's it! 🎉
Once you've published the survey, you can sit back and watch the responses come in. Prolific will take care of the rest.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -84,6 +84,7 @@ export const navigation: Array<NavGroup> = [
{ title: "Hidden Fields", href: "/link-surveys/hidden-fields" },
{ title: "Start At Question", href: "/link-surveys/start-at-question" },
{ title: "Embed Surveys Anywhere", href: "/link-surveys/embed-surveys" },
{ title: "Market Research Panel", href: "/link-surveys/market-research-panel" },
{ title: "Multi Language Surveys", href: "/global/multi-language-surveys" },
{ title: "User Metadata", href: "/global/metadata" },
{ title: "Custom Styling", href: "/global/overwrite-styling" }, // global

View File

@@ -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>
);

View File

@@ -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>
);
};

View File

@@ -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