Skip to content

Commit f2c915f

Browse files
committed
Dashboard: Show upsell card on support page for free plan
1 parent a48329b commit f2c915f

File tree

5 files changed

+64
-29
lines changed

5 files changed

+64
-29
lines changed

apps/dashboard/src/@/components/blocks/upsell-wrapper.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { CrownIcon, LockIcon, SparklesIcon } from "lucide-react";
3+
import { CrownIcon, LockIcon } from "lucide-react";
44
import Link from "next/link";
55
import type React from "react";
66
import type { Team } from "@/api/team";
@@ -111,18 +111,15 @@ export function UpsellContent(props: {
111111
<CardContent className="space-y-6">
112112
{props.benefits && props.benefits.length > 0 && (
113113
<div className="space-y-3">
114-
<h4 className="font-semibold text-muted-foreground text-sm uppercase tracking-wide">
115-
What you'll get:
114+
<h4 className="font-semibold text-foreground text-sm capitalize text-center">
115+
What you'll get
116116
</h4>
117-
<div className="grid gap-2">
117+
<div className="grid gap-1.5">
118118
{props.benefits.map((benefit) => (
119119
<div
120-
className="flex items-center gap-3"
120+
className="flex items-center justify-center gap-3"
121121
key={benefit.description}
122122
>
123-
<div className="flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-accent">
124-
<SparklesIcon className="h-3 w-3 text-success-text" />
125-
</div>
126123
<span className="text-sm">{benefit.description}</span>
127124
{benefit.status === "soon" && (
128125
<Badge className="text-xs" variant="secondary">

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/_components/SupportHeader.tsx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,41 @@ import Link from "next/link";
33
import { useSelectedLayoutSegment } from "next/navigation";
44
import { Button } from "@/components/ui/button";
55

6-
export function SupportHeader(props: { teamSlug: string }) {
6+
export function SupportHeader(props: {
7+
teamSlug: string;
8+
isFreePlan: boolean;
9+
}) {
710
const layoutSegment = useSelectedLayoutSegment();
811

912
return (
1013
<div className="border-border border-b">
1114
<div className="container flex max-w-5xl flex-col items-start gap-3 py-9 md:flex-row md:items-center">
1215
<div className="flex-1">
1316
<h1 className="font-semibold text-3xl tracking-tight mb-1">
14-
Support
17+
Support Center
1518
</h1>
1619
<p className="text-sm text-muted-foreground">
1720
Create and view support cases for your projects
1821
</p>
1922
</div>
20-
{layoutSegment === null ? (
21-
<Button asChild className="rounded-full gap-2">
22-
<Link href={`/team/${props.teamSlug}/~/support/create`}>
23-
Create Case
24-
</Link>
25-
</Button>
26-
) : (
27-
<Button
28-
asChild
29-
className="rounded-full gap-2 bg-card"
30-
variant="outline"
31-
>
32-
<Link href={`/team/${props.teamSlug}/~/support`}>
33-
View All Cases
34-
</Link>
35-
</Button>
36-
)}
23+
{!props.isFreePlan &&
24+
(layoutSegment === null ? (
25+
<Button asChild className="rounded-full gap-2">
26+
<Link href={`/team/${props.teamSlug}/~/support/create`}>
27+
Create Case
28+
</Link>
29+
</Button>
30+
) : (
31+
<Button
32+
asChild
33+
className="rounded-full gap-2 bg-card"
34+
variant="outline"
35+
>
36+
<Link href={`/team/${props.teamSlug}/~/support`}>
37+
View All Cases
38+
</Link>
39+
</Button>
40+
))}
3741
</div>
3842
</div>
3943
);

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/create/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { notFound } from "next/navigation";
1+
import { notFound, redirect } from "next/navigation";
22
import { getAuthToken } from "@/api/auth-token";
33
import { getTeamBySlug } from "@/api/team";
44
import { CreateSupportCase } from "../_components/CreateSupportCase";
@@ -19,5 +19,9 @@ export default async function CreatePage(props: {
1919
notFound();
2020
}
2121

22+
if (team.billingPlan === "free") {
23+
redirect(`/team/${params.team_slug}/~/support`);
24+
}
25+
2226
return <CreateSupportCase authToken={token} team={team} />;
2327
}

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ export default async function Layout(props: {
1515

1616
return (
1717
<div className="flex grow flex-col">
18-
<SupportHeader teamSlug={team.slug} />
18+
<SupportHeader
19+
teamSlug={team.slug}
20+
isFreePlan={team.billingPlan === "free"}
21+
/>
1922
<div className="container max-w-5xl pt-6 pb-10 flex flex-col grow">
2023
{props.children}
2124
</div>

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/page.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { XIcon } from "lucide-react";
22
import { notFound } from "next/navigation";
33
import { getAuthToken } from "@/api/auth-token";
44
import { getTeamBySlug } from "@/api/team";
5+
import { UpsellContent } from "@/components/blocks/upsell-wrapper";
56
import { tryCatch } from "@/utils/try-catch";
67
import { SupportsCaseList } from "./_components/case-list";
78
import { getSupportTicketsByTeam } from "./apis/tickets";
@@ -22,6 +23,31 @@ export default async function Page(props: {
2223
notFound();
2324
}
2425

26+
if (team.billingPlan === "free") {
27+
return (
28+
<div className="flex flex-col grow justify-center items-center">
29+
<UpsellContent
30+
currentPlan={team.billingPlan}
31+
featureDescription="Create support cases for your projects"
32+
featureName="Support Center"
33+
requiredPlan="starter"
34+
teamSlug={params.team_slug}
35+
benefits={[
36+
{
37+
description:
38+
"Create & Manage all your support requests in one place",
39+
status: "available",
40+
},
41+
{
42+
description: "Personalized Assistance tailored to your use case",
43+
status: "available",
44+
},
45+
]}
46+
/>
47+
</div>
48+
);
49+
}
50+
2551
const supportedTicketsResult = await tryCatch(
2652
getSupportTicketsByTeam({
2753
authToken: token,
@@ -37,6 +63,7 @@ export default async function Page(props: {
3763
<XIcon className="size-5 text-muted-foreground" />
3864
</div>
3965
<p className="text-sm">Failed to load support tickets</p>
66+
<p>{supportedTicketsResult.error.message}</p>
4067
</div>
4168
</div>
4269
);

0 commit comments

Comments
 (0)