mirror of
https://github.com/lukevella/rallly.git
synced 2025-08-06 09:59:00 +02:00
✨ Add more paywall triggers
This commit is contained in:
parent
9ff5d907a0
commit
0b808259ab
1 changed files with 149 additions and 127 deletions
|
@ -6,6 +6,7 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@rallly/ui/card";
|
} from "@rallly/ui/card";
|
||||||
|
import { useDialog } from "@rallly/ui/dialog";
|
||||||
import { FormField } from "@rallly/ui/form";
|
import { FormField } from "@rallly/ui/form";
|
||||||
import { Switch } from "@rallly/ui/switch";
|
import { Switch } from "@rallly/ui/switch";
|
||||||
import { AtSignIcon, EyeIcon, MessageCircleIcon, VoteIcon } from "lucide-react";
|
import { AtSignIcon, EyeIcon, MessageCircleIcon, VoteIcon } from "lucide-react";
|
||||||
|
@ -13,8 +14,10 @@ import React from "react";
|
||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
import { Trans } from "react-i18next";
|
import { Trans } from "react-i18next";
|
||||||
|
|
||||||
|
import { PayWallDialog } from "@/components/pay-wall-dialog";
|
||||||
import { ProFeatureBadge } from "@/components/pro-feature-badge";
|
import { ProFeatureBadge } from "@/components/pro-feature-badge";
|
||||||
import { usePlan } from "@/contexts/plan";
|
import { usePlan } from "@/contexts/plan";
|
||||||
|
import { usePostHog } from "@/utils/posthog";
|
||||||
|
|
||||||
export type PollSettingsFormData = {
|
export type PollSettingsFormData = {
|
||||||
requireParticipantEmail: boolean;
|
requireParticipantEmail: boolean;
|
||||||
|
@ -46,33 +49,29 @@ const SettingTitle = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Setting = ({
|
const Setting = ({ children }: React.PropsWithChildren) => {
|
||||||
children,
|
|
||||||
disabled,
|
|
||||||
}: React.PropsWithChildren<{ disabled?: boolean }>) => {
|
|
||||||
const Component = disabled ? "div" : "label";
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<label
|
||||||
className={cn(
|
className={cn(
|
||||||
disabled
|
"cursor-pointer bg-white hover:bg-gray-50 active:bg-gray-100",
|
||||||
? "bg-muted-background text-muted-foreground"
|
|
||||||
: "cursor-pointer bg-white hover:bg-gray-50 active:bg-gray-100",
|
|
||||||
"flex select-none justify-between gap-x-4 gap-y-2.5 rounded-md border p-3 sm:flex-row ",
|
"flex select-none justify-between gap-x-4 gap-y-2.5 rounded-md border p-3 sm:flex-row ",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Component>
|
</label>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
const form = useFormContext<PollSettingsFormData>();
|
const form = useFormContext<PollSettingsFormData>();
|
||||||
|
const posthog = usePostHog();
|
||||||
|
const paywallDialog = useDialog();
|
||||||
const plan = usePlan();
|
const plan = usePlan();
|
||||||
|
|
||||||
const isFree = plan === "free";
|
const isFree = plan === "free";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex justify-between gap-x-4">
|
<div className="flex justify-between gap-x-4">
|
||||||
|
@ -118,7 +117,7 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="requireParticipantEmail"
|
name="requireParticipantEmail"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Setting disabled={isFree}>
|
<Setting>
|
||||||
<AtSignIcon className="size-5 shrink-0 translate-y-0.5" />
|
<AtSignIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||||
<SettingContent>
|
<SettingContent>
|
||||||
<SettingTitle pro>
|
<SettingTitle pro>
|
||||||
|
@ -129,10 +128,17 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
</SettingTitle>
|
</SettingTitle>
|
||||||
</SettingContent>
|
</SettingContent>
|
||||||
<Switch
|
<Switch
|
||||||
disabled={isFree}
|
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
|
if (isFree) {
|
||||||
|
paywallDialog.trigger();
|
||||||
|
posthog?.capture("trigger paywall", {
|
||||||
|
setting: "require-participant-email",
|
||||||
|
from: "poll-settings",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
field.onChange(checked);
|
field.onChange(checked);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
@ -142,7 +148,7 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="hideParticipants"
|
name="hideParticipants"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Setting disabled={isFree}>
|
<Setting>
|
||||||
<EyeIcon className="size-5 shrink-0 translate-y-0.5" />
|
<EyeIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||||
<SettingContent>
|
<SettingContent>
|
||||||
<SettingTitle pro>
|
<SettingTitle pro>
|
||||||
|
@ -153,10 +159,17 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
</SettingTitle>
|
</SettingTitle>
|
||||||
</SettingContent>
|
</SettingContent>
|
||||||
<Switch
|
<Switch
|
||||||
disabled={isFree}
|
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
|
if (isFree) {
|
||||||
|
paywallDialog.trigger();
|
||||||
|
posthog?.capture("trigger paywall", {
|
||||||
|
setting: "hide-participants",
|
||||||
|
from: "poll-settings",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
field.onChange(checked);
|
field.onChange(checked);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
@ -166,7 +179,7 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="hideScores"
|
name="hideScores"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Setting disabled={isFree}>
|
<Setting>
|
||||||
<VoteIcon className="size-5 shrink-0 translate-y-0.5" />
|
<VoteIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||||
<SettingContent>
|
<SettingContent>
|
||||||
<SettingTitle htmlFor={field.name} pro>
|
<SettingTitle htmlFor={field.name} pro>
|
||||||
|
@ -178,10 +191,17 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
</SettingContent>
|
</SettingContent>
|
||||||
<Switch
|
<Switch
|
||||||
id={field.name}
|
id={field.name}
|
||||||
disabled={isFree}
|
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
|
if (isFree) {
|
||||||
|
paywallDialog.trigger();
|
||||||
|
posthog?.capture("trigger paywall", {
|
||||||
|
setting: "hide-scores",
|
||||||
|
from: "poll-settings",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
field.onChange(checked);
|
field.onChange(checked);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
@ -191,5 +211,7 @@ export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||||
</CardContent>
|
</CardContent>
|
||||||
{children}
|
{children}
|
||||||
</Card>
|
</Card>
|
||||||
|
<PayWallDialog {...paywallDialog.dialogProps} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue