Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 6 additions & 28 deletions app/dashboard/success/page.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import { Metadata } from "next";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Check } from "lucide-react";

import { SuccessCard } from "@/components/dashboard/success-card";
import { getUserAndSubscription } from "@/lib/data-fetching";

export const metadata: Metadata = {
title: "Subscription Upgrade Success",
description: "Page for successful checkout of annual subscription upgrade",
};

export default function DashboardSuccess() {
return (
<div className="flex min-h-screen items-center justify-center bg-background">
<Card className="mx-4 w-full max-w-md">
<CardContent className="pt-6 text-center">
<div className="mb-6">
<div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-900">
<Check className="h-6 w-6 text-green-600 dark:text-green-400" />
</div>
<h1 className="mb-2 text-2xl font-bold tracking-tighter">
Subscription Upgraded
</h1>
<p className="text-muted-foreground">
Thank you! Your subscription has been successfully upgraded to
annual.
</p>
</div>
<Link href="/dashboard">
<Button className="w-full">Return to Dashboard</Button>
</Link>
</CardContent>
</Card>
</div>
);
export default async function DashboardSuccess() {
const { openAppQueryParams } = await getUserAndSubscription();
return <SuccessCard openAppQueryParams={openAppQueryParams} />;
}
66 changes: 66 additions & 0 deletions components/dashboard/success-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"use client";

import React, { useEffect } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Check } from "lucide-react";
import { isAllowedUrl } from "@/lib/utils";
import { toast } from "sonner";

const DEFAULT_OPEN_APP_CALLBACK = "pearai://pearai.pearai/auth";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constant is duplicated. Consider defining it in a shared constants file and importing it where needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's reuse existing variable

export const SuccessCard = ({
openAppQueryParams,
}: {
openAppQueryParams: string | URLSearchParams;
}) => {
const router = useRouter();

useEffect(() => {
const openApp = async () => {
const callbackUrl = DEFAULT_OPEN_APP_CALLBACK + "?" + openAppQueryParams;

try {
const finalUrl = new URL(callbackUrl);

if (!isAllowedUrl(finalUrl)) {
throw new Error("Unsafe URL detected.");
}

router.push(finalUrl.toString());
} catch (error) {
console.error("Error opening PearAI app:", error);
toast.error(
"An error occurred while opening the PearAI app. Please try again.",
);
}
};

openApp();
}, [openAppQueryParams, router]);

return (
<div className="flex min-h-screen items-center justify-center bg-background">
<Card className="mx-4 w-full max-w-md">
<CardContent className="pt-6 text-center">
<div className="mb-6">
<div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-900">
<Check className="h-6 w-6 text-green-600 dark:text-green-400" />
</div>
<h1 className="mb-2 text-2xl font-bold tracking-tighter">
Subscription Upgraded
</h1>
<p className="text-muted-foreground">
Thank you! Your subscription has been successfully upgraded to
annual.
</p>
</div>
<Link href="/dashboard">
<Button className="w-full">Return to Dashboard</Button>
</Link>
</CardContent>
</Card>
</div>
);
};