mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-28 17:56:37 +02:00
✨ Use new Pay-Wall Dialog in layout
This commit is contained in:
parent
92f294f40f
commit
db78ad01b1
5 changed files with 101 additions and 89 deletions
|
@ -5,6 +5,7 @@ import { MobileNavigation } from "@/app/[locale]/(admin)/mobile-navigation";
|
|||
import { ProBadge } from "@/app/[locale]/(admin)/pro-badge";
|
||||
import { Sidebar } from "@/app/[locale]/(admin)/sidebar";
|
||||
import { LogoLink } from "@/app/components/logo-link";
|
||||
import { PayWallDialog } from "@/components/pay-wall-dialog";
|
||||
|
||||
export default async function Layout({
|
||||
children,
|
||||
|
@ -12,24 +13,26 @@ export default async function Layout({
|
|||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col pb-16 md:pb-0">
|
||||
<div
|
||||
className={cn(
|
||||
"fixed inset-y-0 z-50 hidden w-72 shrink-0 flex-col gap-y-4 overflow-y-auto p-6 md:flex",
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<LogoLink />
|
||||
<ProBadge />
|
||||
<PayWallDialog>
|
||||
<div className="flex flex-col pb-16 md:pb-0">
|
||||
<div
|
||||
className={cn(
|
||||
"fixed inset-y-0 z-50 hidden w-72 shrink-0 flex-col gap-y-4 overflow-y-auto p-6 md:flex",
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<LogoLink />
|
||||
<ProBadge />
|
||||
</div>
|
||||
<Sidebar />
|
||||
</div>
|
||||
<div className={cn("grow space-y-4 p-3 md:ml-72 md:p-4 lg:p-6")}>
|
||||
<div className="max-w-5xl">{children}</div>
|
||||
</div>
|
||||
<div className="fixed bottom-0 z-20 flex h-16 w-full flex-col justify-center bg-gray-100/90 backdrop-blur-md md:hidden">
|
||||
<MobileNavigation />
|
||||
</div>
|
||||
<Sidebar />
|
||||
</div>
|
||||
<div className={cn("grow space-y-4 p-3 md:ml-72 md:p-4 lg:p-6")}>
|
||||
<div className="max-w-5xl">{children}</div>
|
||||
</div>
|
||||
<div className="fixed bottom-0 z-20 flex h-16 w-full flex-col justify-center bg-gray-100/90 backdrop-blur-md md:hidden">
|
||||
<MobileNavigation />
|
||||
</div>
|
||||
</div>
|
||||
</PayWallDialog>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { cn } from "@rallly/ui";
|
||||
import { Button } from "@rallly/ui/button";
|
||||
import { DialogTrigger } from "@rallly/ui/dialog";
|
||||
import { Icon } from "@rallly/ui/icon";
|
||||
import {
|
||||
ArrowUpRightIcon,
|
||||
|
@ -19,6 +20,7 @@ import Link from "next/link";
|
|||
import { usePathname } from "next/navigation";
|
||||
|
||||
import { CurrentUserAvatar } from "@/components/current-user-avatar";
|
||||
import { PayWallDialog } from "@/components/pay-wall-dialog";
|
||||
import { ProBadge } from "@/components/pro-badge";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { IfGuest, useUser } from "@/components/user-provider";
|
||||
|
@ -102,24 +104,25 @@ export function Sidebar() {
|
|||
<ul role="list" className="-mx-2 space-y-1">
|
||||
<IfFreeUser>
|
||||
<li>
|
||||
<Link
|
||||
href="/settings/billing"
|
||||
className="mb-4 grid rounded-md border bg-gray-50 px-4 py-3 focus:border-gray-300 focus:bg-gray-200"
|
||||
>
|
||||
<span className="mb-2 flex items-center gap-x-2">
|
||||
<SparklesIcon className="size-5 text-gray-400" />
|
||||
<span className="text-sm font-bold">
|
||||
<Trans i18nKey="upgrade" />
|
||||
</span>
|
||||
<ProBadge />
|
||||
</span>
|
||||
<span className="text-sm leading-relaxed text-gray-500">
|
||||
<Trans
|
||||
i18nKey="unlockFeatures"
|
||||
defaults="Unlock all Pro features."
|
||||
/>
|
||||
</span>
|
||||
</Link>
|
||||
<PayWallDialog>
|
||||
<DialogTrigger asChild>
|
||||
<button className="mb-4 flex w-full flex-col rounded-md border bg-gray-50 px-4 py-3 focus:border-gray-300 focus:bg-gray-200">
|
||||
<span className="mb-2 flex items-center gap-x-2">
|
||||
<SparklesIcon className="size-5 text-gray-400" />
|
||||
<span className="text-sm font-bold">
|
||||
<Trans i18nKey="upgrade" />
|
||||
</span>
|
||||
<ProBadge />
|
||||
</span>
|
||||
<span className="text-sm leading-relaxed text-gray-500">
|
||||
<Trans
|
||||
i18nKey="unlockFeatures"
|
||||
defaults="Unlock all Pro features."
|
||||
/>
|
||||
</span>
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
</PayWallDialog>
|
||||
</li>
|
||||
</IfFreeUser>
|
||||
<IfGuest>
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
import { useRouter } from "next/navigation";
|
||||
|
||||
import { DuplicateForm } from "@/app/[locale]/poll/[urlId]/duplicate-form";
|
||||
import { PayWallDialogContent } from "@/app/[locale]/poll/[urlId]/pay-wall-dialog-content";
|
||||
import { trpc } from "@/app/providers";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { usePostHog } from "@/utils/posthog";
|
||||
|
@ -30,54 +29,52 @@ export function DuplicateDialog({
|
|||
const router = useRouter();
|
||||
return (
|
||||
<Dialog {...props}>
|
||||
<PayWallDialogContent>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans i18nKey="duplicate" />
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans i18nKey="duplicateDescription" />
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DuplicateForm
|
||||
name={formName}
|
||||
defaultValues={{
|
||||
title: pollTitle,
|
||||
}}
|
||||
onSubmit={(data) => {
|
||||
duplicate.mutate(
|
||||
{ pollId, newTitle: data.title },
|
||||
{
|
||||
onSuccess: async (res) => {
|
||||
posthog?.capture("duplicate poll", {
|
||||
pollId,
|
||||
newPollId: res.id,
|
||||
});
|
||||
queryClient.invalidate();
|
||||
router.push(`/poll/${res.id}`);
|
||||
},
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans i18nKey="duplicate" />
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans i18nKey="duplicateDescription" />
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DuplicateForm
|
||||
name={formName}
|
||||
defaultValues={{
|
||||
title: pollTitle,
|
||||
}}
|
||||
onSubmit={(data) => {
|
||||
duplicate.mutate(
|
||||
{ pollId, newTitle: data.title },
|
||||
{
|
||||
onSuccess: async (res) => {
|
||||
posthog?.capture("duplicate poll", {
|
||||
pollId,
|
||||
newPollId: res.id,
|
||||
});
|
||||
queryClient.invalidate();
|
||||
router.push(`/poll/${res.id}`);
|
||||
},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button>
|
||||
<Trans i18nKey="cancel" />
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<Button
|
||||
type="submit"
|
||||
loading={duplicate.isLoading}
|
||||
variant="primary"
|
||||
form={formName}
|
||||
>
|
||||
<Trans i18nKey="duplicate" />
|
||||
},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button>
|
||||
<Trans i18nKey="cancel" />
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</PayWallDialogContent>
|
||||
</DialogClose>
|
||||
<Button
|
||||
type="submit"
|
||||
loading={duplicate.isLoading}
|
||||
variant="primary"
|
||||
form={formName}
|
||||
>
|
||||
<Trans i18nKey="duplicate" />
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
"use client";
|
||||
|
||||
import { pricingData } from "@rallly/billing/pricing";
|
||||
import { Badge } from "@rallly/ui/badge";
|
||||
import { Dialog, DialogContent, DialogProps } from "@rallly/ui/dialog";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogProps,
|
||||
useDialog,
|
||||
} from "@rallly/ui/dialog";
|
||||
import { RadioGroup, RadioGroupItem } from "@rallly/ui/radio-group";
|
||||
import { m } from "framer-motion";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { Trans } from "@/components/trans";
|
||||
import { UpgradeButton } from "@/components/upgrade-button";
|
||||
|
@ -22,11 +29,13 @@ const monthlyPriceAnnualRate = (pricingData.yearly.amount / 100 / 12).toFixed(
|
|||
2,
|
||||
);
|
||||
|
||||
export function PayWallDialogContent(props: DialogProps) {
|
||||
const [period, setPeriod] = useState("yearly");
|
||||
export function PayWallDialog({ children, ...forwardedProps }: DialogProps) {
|
||||
const dialog = useDialog();
|
||||
const [period, setPeriod] = React.useState("yearly");
|
||||
|
||||
return (
|
||||
<Dialog {...props}>
|
||||
<Dialog {...dialog.dialogProps} {...forwardedProps}>
|
||||
{children}
|
||||
<DialogContent className="w-[600px] p-4">
|
||||
<div className="space-y-6">
|
||||
<header className="pt-4">
|
|
@ -27,8 +27,8 @@ import Link from "next/link";
|
|||
import * as React from "react";
|
||||
|
||||
import { DuplicateDialog } from "@/app/[locale]/poll/[urlId]/duplicate-dialog";
|
||||
import { PayWallDialogContent } from "@/app/[locale]/poll/[urlId]/pay-wall-dialog-content";
|
||||
import { trpc } from "@/app/providers";
|
||||
import { PayWallDialog } from "@/components/pay-wall-dialog";
|
||||
import { FinalizePollDialog } from "@/components/poll/manage-poll/finalize-poll-dialog";
|
||||
import { ProFeatureBadge } from "@/components/pro-feature-badge";
|
||||
import { Trans } from "@/components/trans";
|
||||
|
@ -274,7 +274,7 @@ const ManagePoll: React.FunctionComponent<{
|
|||
{...duplicateDialog.dialogProps}
|
||||
/>
|
||||
<FinalizePollDialog {...finalizeDialog.dialogProps} />
|
||||
<PayWallDialogContent {...paywallDialog.dialogProps} />
|
||||
<PayWallDialog {...paywallDialog.dialogProps} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue