Merge branch 'main' into surveyBg

This commit is contained in:
Anjy Gupta
2023-10-31 20:39:18 +05:30
committed by GitHub
12 changed files with 276 additions and 142 deletions
+4 -9
View File
@@ -1,4 +1,7 @@
<div id="top"></div>
[<img src="ph.png">](https://www.producthunt.com/posts/formbricks)
<p align="center">
<a href="https://formbricks.com">
<img width="120" alt="Open Source Experience Management Solution Qualtrics Alternative Logo" src="https://github.com/formbricks/formbricks/assets/72809645/0086704f-bee7-4d38-9cc8-fa42ee59e004">
@@ -6,7 +9,7 @@
<h3 align="center">Formbricks</h3>
<p align="center">
The Open Source Survey & Experience Management solution for fast-growing companies
The Open Source Survey Toolbox
<br />
<a href="https://formbricks.com/">Website</a> | <a href="https://formbricks.com/discord">Join Discord community</a>
</p>
@@ -34,14 +37,6 @@
<a href="https://trendshift.io/repositories/2570" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2570" alt="Trendshift Badge for formbricks/formbricks" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
<img width="1527" alt="formtribe hackathon" src="https://github.com/formbricks/formbricks/assets/72809645/addc3a5b-421c-4c8d-8be2-eedf087100ed">
## 🔥 The FormTribe Hackathon is on!
To celebrate Hacktoberfest, we've launched our FormTribe hackathon. Write code or perform non-code side quests to collect points and increase your chances of winning the MacBook Air M2!
**Join the lottery with a [single tweet!](https://formtribe.com). All info on [formtribe.com](https://formtribe.com)**
## ✨ About Formbricks
<img width="1527" alt="formbricks-sneak" src="https://github-production-user-asset-6210df.s3.amazonaws.com/675065/249441967-ccb89ea3-82b4-4bf2-8d2c-528721ec313b.png">
@@ -1,14 +1,11 @@
import HackIconGold from "@/images/formtribe/hack-icon-gold.svg";
import PHIcon from "@/images/formtribe/ph-logo.png";
import Image from "next/image";
import Link from "next/link";
export const GitHubSponsorship: React.FC = () => {
return (
<div className="mx-4 my-4 mb-12 mt-12 rounded-xl bg-gradient-to-br from-slate-100 to-slate-200 px-4 py-8 dark:from-slate-800 dark:via-slate-800 dark:to-slate-700 sm:px-6 sm:pb-12 sm:pt-8 md:max-w-none lg:mt-6 lg:px-8 lg:pt-8">
<style jsx>{`
@media (min-width: 426px);
`}</style>
<div className="right-24 lg:absolute">
<Link href="https://www.producthunt.com/posts/formbricks" target="_blank">
<div className="my-12 grid w-full grid-cols-3 rounded-2xl border border-[#ff6154] bg-gradient-to-br from-slate-100 to-slate-200 p-12 transition-all hover:scale-105 dark:from-slate-800 dark:via-slate-800 dark:to-slate-700">
{/* <Image
src={GitHubMarkDark}
alt="GitHub Sponsors Formbricks badge"
@@ -23,20 +20,28 @@ export const GitHubSponsorship: React.FC = () => {
height={100}
className="mr-12 hidden dark:block md:mr-4"
/> */}
<Image src={HackIconGold} alt="Hacktober Icon Gold" width={100} className="mr-12 md:mr-4" />
<div className="col-span-2">
<h2 className="text-2xl font-bold tracking-tight text-slate-800 dark:text-slate-200 lg:text-2xl">
We are live on ProductHunt today 🚀
</h2>
<p className="lg:text-md mt-2 max-w-3xl text-slate-500 dark:text-slate-400">
Support our open source project with an upvote and comment.
<span>
<Link
href="https://www.producthunt.com/posts/formbricks"
className="ml-2 underline decoration-[#ff6154] underline-offset-4"
target="_blank">
View launch post.
</Link>
</span>
</p>
</div>
<div className="flex items-center justify-end">
<Image src={PHIcon} alt="Product Hunt Logo" width={80} className="" />
</div>
</div>
<h2 className="mt-4 text-2xl font-bold tracking-tight text-slate-800 dark:text-slate-200 lg:text-2xl">
The FormTribe goes Hacktoberfest 🥨
</h2>
<p className="lg:text-md mt-4 max-w-3xl text-slate-500 dark:text-slate-400">
Write code, win a Mac! We&apos;re running a Hacktoberfest community Hackathon:
<span>
<Link href="/formtribe" className="decoration-brand-dark ml-2 underline underline-offset-4">
Find out more.
</Link>
</span>
</p>
</div>
</Link>
);
};
+16 -20
View File
@@ -20,30 +20,26 @@ export const Hero: React.FC = ({}) => {
<div className="relative">
<div className="px-4 pb-20 pt-16 text-center sm:px-6 lg:px-8 lg:pb-32 lg:pt-20">
<a
href="https://formbricks.com/formtribe"
href="https://www.producthunt.com/posts/formbricks"
target="_blank"
className="border-brand-dark xs:text-sm animate-bounce rounded-full border px-4 py-1.5 text-xs text-slate-500 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-800">
The FormTribe Hackathon is on 🔥
Support us on Product Hunt 🚀
<ChevronRightIcon className="inline h-5 w-5 text-slate-300" />
</a>
<h1 className="mt-10 text-3xl font-bold tracking-tight text-slate-800 dark:text-slate-200 sm:text-4xl md:text-5xl">
<span className="xl:inline">Open-source Experience Management</span>
<span className="xl:inline">The Open Source Survey Suite</span>
</h1>
<p className="xs:max-w-none mx-auto mt-3 max-w-xs text-base text-slate-500 dark:text-slate-400 sm:text-lg md:mt-5 md:text-xl">
Understand what customers think & feel about your product.
<br />
<span className="hidden md:block">
Natively integrate user research with minimal dev attention,{" "}
<span className="decoration-brand-dark underline underline-offset-4">privacy-first.</span>
</span>
Run link surveys, in-app surveys and email surveys in one app {" "}
<span className="decoration-brand-dark underline underline-offset-4">all privacy-first.</span>
</p>
<div className="mx-auto mt-5 max-w-3xl items-center px-4 sm:flex sm:justify-center md:mt-8 md:space-x-8 md:px-0">
<div className="mx-auto mt-5 max-w-2xl items-center px-4 sm:flex sm:justify-center md:mt-6 md:space-x-8 md:px-0">
<p className="hidden whitespace-nowrap pt-3 text-xs text-slate-400 dark:text-slate-500 md:block">
Trusted by
</p>
<div className="grid grid-cols-4 items-center gap-5 pt-2 md:gap-8">
<div className="grid grid-cols-4 items-center gap-6 pt-2 md:gap-8">
<Image
src={CalLogoLight}
alt="Cal Logo"
@@ -68,12 +64,6 @@ export const Hero: React.FC = ({}) => {
className="hidden rounded-lg pb-1 hover:opacity-100 dark:block md:opacity-50"
width={200}
/>
<Image
src={ClovyrLogo}
alt="Clovyr Logo"
className="rounded-lg pb-1 hover:opacity-100 md:opacity-50"
width={200}
/>
<Image
src={NILogoDark}
alt="Neverinstall Logo"
@@ -86,6 +76,12 @@ export const Hero: React.FC = ({}) => {
className="hidden pb-1 hover:opacity-100 dark:block md:opacity-50"
width={200}
/>
<Image
src={ClovyrLogo}
alt="Clovyr Logo"
className="rounded-lg pb-1 hover:opacity-100 md:opacity-50"
width={200}
/>
</div>
</div>
<div className="hidden pt-10 md:block">
@@ -102,10 +98,10 @@ export const Hero: React.FC = ({}) => {
variant="secondary"
className="px-6"
onClick={() => {
router.push("/demo");
plausible("Hero_CTA_LaunchDemo");
router.push("https://www.producthunt.com/posts/formbricks");
/* plausible("Hero_CTA_LaunchDemo"); */
}}>
Live demo
Support Launch 🚀
</Button>
</div>
</div>
@@ -120,9 +120,9 @@ export default function Header() {
: "relative";
return (
<Popover className={`${stickyNavClass}`} as="header">
<a href="https://www.producthunt.com/products/formbricks" target="_blank">
<a href="https://www.producthunt.com/posts/formbricks" target="_blank">
<div className="hidden bg-[#ff6154] px-4 py-2 text-center text-sm text-white md:block lg:py-0">
We&apos;re launching soon on Product Hunt - get notified 🚀
We&apos;re live on Product Hunt - Show your support for Open Source 🚀
</div>
</a>
<div className="flex items-center justify-between px-4 py-6 sm:px-6 md:justify-start ">
@@ -1,14 +1,14 @@
import { Slider } from "@/components/shared/Slider";
import { useState } from "react";
const ProductItem = ({ label, usersCount, price, onSliderChange }) => (
const LinkSurveySlider = ({ label, usersCount, price, onSliderChange }) => (
<div className="mt-12">
<div className="mb-2 flex items-center gap-x-2 md:gap-x-4">
<div className="md:text-md w-3/6 text-left text-sm font-medium text-slate-700 dark:text-slate-200">
{label}
</div>
<div className="md:text-md w-2/6 text-center text-sm font-medium text-slate-700 dark:text-slate-200">
{Math.round(usersCount).toLocaleString()} MTU
{Math.round(usersCount).toLocaleString()} Submissions
</div>
<div className="md:text-md flex w-1/6 items-center justify-end text-center text-sm font-medium text-slate-700 dark:text-slate-200 md:justify-center">
<span>${price.toFixed(2)}</span>
@@ -34,6 +34,72 @@ const ProductItem = ({ label, usersCount, price, onSliderChange }) => (
</div>
);
const InAppSlider = ({ label, usersCount, price, onSliderChange }) => (
<div className="mt-12">
<div className="mb-2 flex items-center gap-x-2 md:gap-x-4">
<div className="md:text-md w-3/6 text-left text-sm font-medium text-slate-700 dark:text-slate-200">
{label}
</div>
<div className="md:text-md w-2/6 text-center text-sm font-medium text-slate-700 dark:text-slate-200">
{Math.round(usersCount).toLocaleString()} Submissions
</div>
<div className="md:text-md flex w-1/6 items-center justify-end text-center text-sm font-medium text-slate-700 dark:text-slate-200 md:justify-center">
<span>${price.toFixed(2)}</span>
</div>
</div>
<div className="my-2 w-5/6 pr-8 md:pr-20">
<Slider
className="slider-class"
defaultValue={[Math.log10(250)]}
min={3}
max={6}
step={0.01}
onValueChange={onSliderChange}
/>
<div className="mt-2 flex items-center justify-between text-sm">
{[3, 4, 5, 6].map((mark) => (
<span key={mark} className="text-slate-600 dark:text-slate-300">
{mark === 3 ? "1K" : mark === 4 ? "10K" : mark === 5 ? "100K" : "1M"}
</span>
))}
</div>
</div>
</div>
);
const UserSegmentationSlider = ({ label, usersCount, price, onSliderChange }) => (
<div className="mt-12">
<div className="mb-2 flex items-center gap-x-2 md:gap-x-4">
<div className="md:text-md w-3/6 text-left text-sm font-medium text-slate-700 dark:text-slate-200">
{label}
</div>
<div className="md:text-md w-2/6 text-center text-sm font-medium text-slate-700 dark:text-slate-200">
{Math.round(usersCount).toLocaleString()} Submissions
</div>
<div className="md:text-md flex w-1/6 items-center justify-end text-center text-sm font-medium text-slate-700 dark:text-slate-200 md:justify-center">
<span>${price.toFixed(2)}</span>
</div>
</div>
<div className="my-2 w-5/6 pr-8 md:pr-20">
<Slider
className="slider-class"
defaultValue={[Math.log10(250)]}
min={3}
max={6}
step={0.01}
onValueChange={onSliderChange}
/>
<div className="mt-2 flex items-center justify-between text-sm">
{[3, 4, 5, 6].map((mark) => (
<span key={mark} className="text-slate-600 dark:text-slate-300">
{mark === 3 ? "1K" : mark === 4 ? "10K" : mark === 5 ? "100K" : "1M"}
</span>
))}
</div>
</div>
</div>
);
const Headers = () => (
<div className="mb-4 flex justify-between">
<h3 className="text-base font-semibold text-slate-700 dark:text-slate-200 md:text-lg">Product</h3>
@@ -89,16 +155,7 @@ export const PricingCalculator = () => {
<hr className="my-4" />
<ProductItem
label="In Product Surveys"
usersCount={usersCountForInProductSlider}
price={productSurveysPrice}
onSliderChange={(value) => setInProductSlider(value[0])}
/>
<hr className="my-4" />
<ProductItem
<LinkSurveySlider
label="Link Surveys"
usersCount={transformToLog(linkSlider)}
price={0}
@@ -107,6 +164,22 @@ export const PricingCalculator = () => {
<hr className="my-4" />
<InAppSlider
label="Website and In-App Surveys"
usersCount={transformToLog(linkSlider)}
price={0}
onSliderChange={(value) => setLinkSlider(value[0])}
/>
<hr className="my-4" />
<UserSegmentationSlider
label="User Segmentation"
usersCount={usersCountForInProductSlider}
price={productSurveysPrice}
onSliderChange={(value) => setInProductSlider(value[0])}
/>
<MonthlyEstimate price={productSurveysPrice} />
</div>
</div>
@@ -1,35 +1,14 @@
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@formbricks/ui/Tooltip";
import { CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "@radix-ui/react-tooltip";
interface SpecialRow {
title: string | JSX.Element;
free: string | JSX.Element;
paid: string | JSX.Element;
}
interface PricingRow {
name: string;
free: string | boolean;
paid: string | boolean;
comingSoon?: boolean;
addOnText?: string;
}
export const PricingTable = ({
leadRow,
pricing,
endRow,
}: {
leadRow: SpecialRow;
pricing: PricingRow[];
endRow: SpecialRow;
}) => {
export const PricingTable = ({ leadRow, pricing, endRow }) => {
return (
<div className="grid grid-cols-1 px-4 md:gap-4 md:px-16 ">
<div className="rounded-xl px-4 md:px-12">
<div className="flex items-center gap-x-4">
<div className="w-1/3 text-left font-semibold text-slate-700 dark:text-slate-200 md:text-xl">
{leadRow.title}
<span className="pl-2 text-sm font-normal text-slate-600">{leadRow.comparison}</span>
</div>
<div
className="flex w-1/3 items-center justify-center text-center text-sm font-semibold
@@ -49,12 +28,12 @@ export const PricingTable = ({
<div className="w-1/3 text-left text-sm text-slate-700 dark:text-slate-200 md:text-base">
{feature.name}
{feature.addOnText && (
<span className=" mx-2 bg-teal-100 p-1 text-xs text-slate-400 dark:bg-slate-700 dark:text-teal-500">
<span className=" mx-3 rounded-full bg-emerald-200 px-2 text-xs text-slate-800 dark:bg-slate-700 dark:text-teal-500">
Addon
</span>
)}
{feature.comingSoon && (
<span className=" mx-2 bg-blue-100 p-1 text-xs text-slate-400 dark:bg-slate-700 dark:text-teal-500">
<span className="mx-3 rounded-full bg-slate-200 px-2 text-xs text-slate-800 dark:bg-slate-700 dark:text-teal-500">
coming soon
</span>
)}
+1 -1
View File
@@ -132,7 +132,7 @@ const nextConfig = {
},
{
source: "/launch",
destination: "https://www.producthunt.com/products/formbricks",
destination: "https://www.producthunt.com/posts/formbricks",
permanent: true,
},
{
@@ -663,7 +663,7 @@ export default function FormTribeHackathon() {
<div className="px-4 pb-16 pt-16 text-center sm:px-6 lg:px-8 lg:pb-32 lg:pt-20">
<a
href="https://www.producthunt.com/products/formbricks"
href="https://www.producthunt.com/posts/formbricks"
target="_blank"
className=" rounded-full border bg-slate-100 px-4 py-1.5 text-sm text-slate-500 hover:scale-105">
Don&apos;t miss the launch! Get notified 🚀
@@ -1126,7 +1126,7 @@ const Breaker = ({ icon, title }) => {
<div className="mt-4 flex items-center justify-center">
<Image src={PHLogo} alt="ph-logo" className="mr-2 h-8 w-8" />
<a
href="https://www.producthunt.com/products/formbricks"
href="https://www.producthunt.com/posts/formbricks"
target="_blank"
className="text-sm font-semibold text-[#ff6154]">
Get notified on Product Hunt.
+121 -45
View File
@@ -2,52 +2,77 @@ import HeroTitle from "@/components/shared/HeroTitle";
import Layout from "@/components/shared/Layout";
import { OpenSourceInfo } from "@/components/shared/OpenSourceInfo";
import { GetStartedWithPricing } from "@/components/shared/PricingGetStarted";
import { PricingCalculator } from "../components/shared/PricingCalculator";
import { PricingTable } from "../components/shared/PricingTable";
import { Button } from "@formbricks/ui/Button";
const inProductSurveys = {
leadRow: {
title: "In-Product Surveys",
title: "Website and In-App Surveys",
comparison: "like HotJar",
free: (
<div>
<span>5000 tracked users</span> <span className="text-slate-400">/mo</span>{" "}
<span>250 Submissions</span> <span className="text-slate-400">/ Month</span>{" "}
</div>
),
paid: "Unlimited",
},
features: [
{ name: "Unlimited Surveys", free: true, paid: true },
{ name: "Granular Targeting", free: true, paid: true },
{ name: "30+ Templates", free: true, paid: true },
{ name: "API Access", free: true, paid: true },
{ name: "Third-Party Integrations", free: true, paid: true },
{ name: "Unlimited Team Members", free: true, paid: true },
{ name: "Unlimited Responses per Survey", free: true, paid: true },
{ name: "Team Role Management", free: false, paid: true },
{ name: "API Access", free: true, paid: true },
{ name: "30+ Templates", free: true, paid: true },
{ name: "Unlimited Responses per Survey", free: false, paid: true },
{ name: "Team Role Management", free: false, paid: true, comingSoon: true },
{ name: "Advanced User Targeting", free: false, paid: true, comingSoon: true },
{ name: "Multi Language Surveys", free: false, paid: true, comingSoon: true },
{
name: "Custom URL for Link Surveys",
free: "10$/mo",
paid: "10$/mo",
addOnText: "Free if you self-host",
},
{
name: "Remove Formbricks Branding",
free: "10$/mo",
paid: "10$/mo",
addOnText: "Free if you self-host",
},
],
endRow: {
title: "In-Product Surveys Pricing",
title: "Website and In-App Surveys",
free: "Free",
paid: (
<div>
<span>Free</span> <span className="text-slate-400">up to 5000 tracked users/mo, then </span>
<span>$0.005</span>
<span className="text-slate-400"> / tracked user</span>
<span>Free</span>{" "}
<span className="text-slate-400">
up to 250 submissions / month <br />
then{" "}
</span>
<span>$0.15</span>
<span className="text-slate-400"> / submission</span>
</div>
),
},
};
const userSegmentation = {
leadRow: {
title: "User Segmentation",
comparison: "like Segment",
free: (
<div>
<span>2500 Users</span> <span className="text-slate-400">/ Month</span>{" "}
</div>
),
paid: "Unlimited",
},
features: [
{ name: "Identify Users", free: true, paid: true },
{ name: "Collect Events", free: true, paid: true },
{ name: "Collect Attributes", free: true, paid: true },
{ name: "Advanced User Targeting", free: false, paid: true, comingSoon: true },
{ name: "Reusable Segments", free: false, paid: true, comingSoon: true },
],
endRow: {
title: "User Segmentation like Segment",
free: "Free",
paid: (
<div>
<span>Free</span>{" "}
<span className="text-slate-400">
up to 2500 users / month <br />
then{" "}
</span>
<span>$0.01</span>
<span className="text-slate-400"> / user</span>
</div>
),
},
@@ -56,6 +81,7 @@ const inProductSurveys = {
const linkSurveys = {
leadRow: {
title: "Link Surveys",
comparison: "like Typeform",
free: <span>Unlimited</span>,
paid: "Unlimited",
},
@@ -64,20 +90,22 @@ const linkSurveys = {
{ name: "Unlimited Surveys", free: true, paid: true },
{ name: "Unlimited Responses", free: true, paid: true },
{ name: "Partial Responses", free: true, paid: true },
{ name: "⚙️ URL Shortener", free: true, paid: true },
{ name: "⚙️ Recall Information", free: true, paid: true },
{ name: "⚙️ Hidden Field Questions", free: true, paid: true },
{ name: "⚙️ Time to Complete Metadata", free: true, paid: true },
{ name: "⚙️ File Upload", free: true, paid: true },
{ name: "⚙️ Signature Question", free: true, paid: true },
{ name: "⚙️ Question Grouping", free: true, paid: true },
{ name: "⚙️ Add Media to Questions", free: true, paid: true },
{ name: "Multi-media Backgrounds", free: true, paid: true },
{ name: "File Upload", free: true, paid: true },
{ name: "Hidden Fields", free: true, paid: true },
{ name: "Single Use Survey Links", free: true, paid: true },
{ name: "Pin-protected Surveys", free: true, paid: true },
{ name: "Custom Styling", free: true, paid: true, comingSoon: true },
{ name: "Recall Information", free: true, paid: true, comingSoon: true },
{ name: "Collect Payments, Signatures and Appointments", free: true, paid: true, comingSoon: true },
{ name: "Custom URL", free: false, paid: true },
{ name: "Remove Formbricks Branding", free: false, paid: true },
],
endRow: {
title: "Link Surveys Pricing",
free: "Free",
paid: "Free",
paid: "$30 / month",
},
};
@@ -90,9 +118,11 @@ const integrations = {
features: [
{ name: "Webhooks", free: true, paid: true },
{ name: "Zapier", free: true, paid: true },
{ name: "Google Sheets", free: true, paid: true },
{ name: "Notion", free: true, paid: true },
{ name: "n8n", free: true, paid: true },
{ name: "Make", free: true, paid: true },
{ name: "Google Sheets", free: true, paid: true },
{ name: "Airtable", free: true, paid: true },
],
endRow: {
title: "Integrations Pricing",
@@ -105,27 +135,73 @@ const PricingPage = () => {
return (
<Layout
title="Pricing | Formbricks Open Source Experience Management"
description="Choose what's best for you! All our plans start free.">
description="All our plans start free - choose what's best for you!">
<div className="relative isolate mx-5 mt-8 overflow-hidden rounded-lg bg-slate-50 px-3 pt-4 shadow-2xl dark:bg-slate-800 sm:px-8 md:pt-8 lg:gap-x-10 lg:px-12 lg:pt-0">
<svg
viewBox="0 0 1024 1024"
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
aria-hidden="true">
<circle
cx={512}
cy={512}
r={512}
fill="url(#759c1415-0410-454c-8f7c-9a820de03641)"
fillOpacity="0.7"
/>
<defs>
<radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
<stop stopColor="#00E6CA" />
<stop offset={0} stopColor="#00C4B8" />
</radialGradient>
</defs>
</svg>
<div className="mx-auto w-full text-center lg:mx-0 lg:flex-auto lg:py-8 lg:text-left">
<h2 className="text-2xl font-bold text-slate-800 dark:text-slate-50 sm:text-3xl">
Launch Special:
<br /> Go Unlimited! Forever!
</h2>
<p className="text-md mt-6 leading-8 text-slate-700 dark:text-slate-50">
Get access to all pro features and unlimited responses + identified users for a flat fee of{" "}
<b>only $99/month.</b>
<br /> <br />
<span className="text-slate-400 dark:text-slate-300">
This deal ends on 31st of October 2023 at 11:59 PM PST.
</span>
</p>
</div>
<div className="mb-8 mt-2 items-center justify-center">
<Button className="w-full justify-center py-2 shadow-sm" href="https://app.formbricks.com/">
Get Started
</Button>
</div>
</div>
<HeroTitle
headingPt1=""
headingTeal="Pricing"
subheading="Choose what's best for you! All our plans start free."
subheading="All our plans start free - choose what's best for you!"
/>
<div className="space-y-24">
<div>
<GetStartedWithPricing showDetailed={true} />
<PricingTable
leadRow={inProductSurveys.leadRow}
pricing={inProductSurveys.features}
endRow={inProductSurveys.endRow}
leadRow={linkSurveys.leadRow}
pricing={linkSurveys.features}
endRow={linkSurveys.endRow}
/>
</div>
<PricingTable
leadRow={linkSurveys.leadRow}
pricing={linkSurveys.features}
endRow={linkSurveys.endRow}
leadRow={inProductSurveys.leadRow}
pricing={inProductSurveys.features}
endRow={inProductSurveys.endRow}
/>
<PricingTable
leadRow={userSegmentation.leadRow}
pricing={userSegmentation.features}
endRow={userSegmentation.endRow}
/>
<PricingTable
@@ -134,7 +210,7 @@ const PricingPage = () => {
endRow={integrations.endRow}
/>
<div>
<PricingCalculator />
{/* <PricingCalculator /> */}
<OpenSourceInfo />
</div>
</div>
@@ -4,6 +4,7 @@ import { transformErrorToDetails } from "@/app/lib/api/validator";
import { createAttributeClass, getAttributeClassByName } from "@formbricks/lib/attributeClass/service";
import { personCache } from "@formbricks/lib/person/cache";
import { getPerson, updatePersonAttribute } from "@formbricks/lib/person/service";
import { surveyCache } from "@formbricks/lib/survey/cache";
import { ZJsPeopleAttributeInput } from "@formbricks/types/js";
import { NextResponse } from "next/server";
@@ -47,15 +48,19 @@ export async function POST(req: Request, { params }): Promise<NextResponse> {
}
// upsert attribute (update or create)
updatePersonAttribute(personId, attributeClass.id, value);
const state = await getUpdatedState(environmentId, personId, sessionId);
await updatePersonAttribute(personId, attributeClass.id, value);
personCache.revalidate({
id: state.person.id,
id: personId,
environmentId,
});
surveyCache.revalidate({
environmentId,
});
const state = await getUpdatedState(environmentId, personId, sessionId);
return responses.successResponse({ ...state }, true);
} catch (error) {
console.error(error);
@@ -5,6 +5,7 @@ import { prisma } from "@formbricks/database";
import { getDisplaysByPersonId, updateDisplay } from "@formbricks/lib/display/service";
import { personCache } from "@formbricks/lib/person/cache";
import { deletePerson, selectPerson, transformPrismaPerson } from "@formbricks/lib/person/service";
import { surveyCache } from "@formbricks/lib/survey/cache";
import { ZJsPeopleUserIdInput } from "@formbricks/types/js";
import { NextResponse } from "next/server";
@@ -102,13 +103,17 @@ export async function POST(req: Request, { params }): Promise<NextResponse> {
const transformedPerson = transformPrismaPerson(returnedPerson);
const state = await getUpdatedState(environmentId, transformedPerson.id, sessionId);
personCache.revalidate({
id: transformedPerson.id,
environmentId: environmentId,
});
surveyCache.revalidate({
environmentId,
});
const state = await getUpdatedState(environmentId, transformedPerson.id, sessionId);
return responses.successResponse({ ...state }, true);
} catch (error) {
console.error(error);
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB