mirror of
https://github.com/lukevella/rallly.git
synced 2025-08-03 00:19:03 +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,
|
||||
CardTitle,
|
||||
} from "@rallly/ui/card";
|
||||
import { useDialog } from "@rallly/ui/dialog";
|
||||
import { FormField } from "@rallly/ui/form";
|
||||
import { Switch } from "@rallly/ui/switch";
|
||||
import { AtSignIcon, EyeIcon, MessageCircleIcon, VoteIcon } from "lucide-react";
|
||||
|
@ -13,8 +14,10 @@ import React from "react";
|
|||
import { useFormContext } from "react-hook-form";
|
||||
import { Trans } from "react-i18next";
|
||||
|
||||
import { PayWallDialog } from "@/components/pay-wall-dialog";
|
||||
import { ProFeatureBadge } from "@/components/pro-feature-badge";
|
||||
import { usePlan } from "@/contexts/plan";
|
||||
import { usePostHog } from "@/utils/posthog";
|
||||
|
||||
export type PollSettingsFormData = {
|
||||
requireParticipantEmail: boolean;
|
||||
|
@ -46,150 +49,169 @@ const SettingTitle = ({
|
|||
);
|
||||
};
|
||||
|
||||
const Setting = ({
|
||||
children,
|
||||
disabled,
|
||||
}: React.PropsWithChildren<{ disabled?: boolean }>) => {
|
||||
const Component = disabled ? "div" : "label";
|
||||
const Setting = ({ children }: React.PropsWithChildren) => {
|
||||
return (
|
||||
<Component
|
||||
<label
|
||||
className={cn(
|
||||
disabled
|
||||
? "bg-muted-background text-muted-foreground"
|
||||
: "cursor-pointer bg-white hover:bg-gray-50 active:bg-gray-100",
|
||||
"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 ",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
|
||||
export const PollSettingsForm = ({ children }: React.PropsWithChildren) => {
|
||||
const form = useFormContext<PollSettingsFormData>();
|
||||
|
||||
const posthog = usePostHog();
|
||||
const paywallDialog = useDialog();
|
||||
const plan = usePlan();
|
||||
|
||||
const isFree = plan === "free";
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex justify-between gap-x-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<CardTitle>
|
||||
<Trans i18nKey="settings" />
|
||||
</CardTitle>
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex justify-between gap-x-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<CardTitle>
|
||||
<Trans i18nKey="settings" />
|
||||
</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
<Trans
|
||||
i18nKey="pollSettingsDescription"
|
||||
defaults="Customize the behaviour of your poll"
|
||||
/>
|
||||
</CardDescription>
|
||||
</div>
|
||||
<CardDescription>
|
||||
<Trans
|
||||
i18nKey="pollSettingsDescription"
|
||||
defaults="Customize the behaviour of your poll"
|
||||
/>
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className={cn("grid gap-2.5")}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="disableComments"
|
||||
render={({ field }) => (
|
||||
<Setting>
|
||||
<MessageCircleIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle htmlFor="disableComments">
|
||||
<Trans i18nKey="disableComments">Disable Comments</Trans>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
id={field.name}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="requireParticipantEmail"
|
||||
render={({ field }) => (
|
||||
<Setting disabled={isFree}>
|
||||
<AtSignIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle pro>
|
||||
<Trans
|
||||
i18nKey="requireParticipantEmailLabel"
|
||||
defaults="Make email address required for participants"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
disabled={isFree}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="hideParticipants"
|
||||
render={({ field }) => (
|
||||
<Setting disabled={isFree}>
|
||||
<EyeIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle pro>
|
||||
<Trans
|
||||
i18nKey="hideParticipantsLabel"
|
||||
defaults="Hide participants from each other"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
disabled={isFree}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="hideScores"
|
||||
render={({ field }) => (
|
||||
<Setting disabled={isFree}>
|
||||
<VoteIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle htmlFor={field.name} pro>
|
||||
<Trans
|
||||
i18nKey="hideScoresLabel"
|
||||
defaults="Hide scores until after a participant has voted"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
id={field.name}
|
||||
disabled={isFree}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
{children}
|
||||
</Card>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className={cn("grid gap-2.5")}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="disableComments"
|
||||
render={({ field }) => (
|
||||
<Setting>
|
||||
<MessageCircleIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle htmlFor="disableComments">
|
||||
<Trans i18nKey="disableComments">Disable Comments</Trans>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
id={field.name}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="requireParticipantEmail"
|
||||
render={({ field }) => (
|
||||
<Setting>
|
||||
<AtSignIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle pro>
|
||||
<Trans
|
||||
i18nKey="requireParticipantEmailLabel"
|
||||
defaults="Make email address required for participants"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
if (isFree) {
|
||||
paywallDialog.trigger();
|
||||
posthog?.capture("trigger paywall", {
|
||||
setting: "require-participant-email",
|
||||
from: "poll-settings",
|
||||
});
|
||||
} else {
|
||||
field.onChange(checked);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="hideParticipants"
|
||||
render={({ field }) => (
|
||||
<Setting>
|
||||
<EyeIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle pro>
|
||||
<Trans
|
||||
i18nKey="hideParticipantsLabel"
|
||||
defaults="Hide participants from each other"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
if (isFree) {
|
||||
paywallDialog.trigger();
|
||||
posthog?.capture("trigger paywall", {
|
||||
setting: "hide-participants",
|
||||
from: "poll-settings",
|
||||
});
|
||||
} else {
|
||||
field.onChange(checked);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="hideScores"
|
||||
render={({ field }) => (
|
||||
<Setting>
|
||||
<VoteIcon className="size-5 shrink-0 translate-y-0.5" />
|
||||
<SettingContent>
|
||||
<SettingTitle htmlFor={field.name} pro>
|
||||
<Trans
|
||||
i18nKey="hideScoresLabel"
|
||||
defaults="Hide scores until after a participant has voted"
|
||||
/>
|
||||
</SettingTitle>
|
||||
</SettingContent>
|
||||
<Switch
|
||||
id={field.name}
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
if (isFree) {
|
||||
paywallDialog.trigger();
|
||||
posthog?.capture("trigger paywall", {
|
||||
setting: "hide-scores",
|
||||
from: "poll-settings",
|
||||
});
|
||||
} else {
|
||||
field.onChange(checked);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Setting>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
{children}
|
||||
</Card>
|
||||
<PayWallDialog {...paywallDialog.dialogProps} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue