@@ -150,7 +152,7 @@ export default async function DashboardPage() {
}
>
-
+
}
>
-
+
}
>
-
+
diff --git a/app/(protected)/dashboard/urls/meta-chart.tsx b/app/(protected)/dashboard/urls/meta-chart.tsx
index 47c18ad..273a6fd 100644
--- a/app/(protected)/dashboard/urls/meta-chart.tsx
+++ b/app/(protected)/dashboard/urls/meta-chart.tsx
@@ -9,8 +9,8 @@ import { TopoJSONMap } from "@unovis/ts";
import { WorldMapTopoJSON } from "@unovis/ts/maps";
import { useTranslations } from "next-intl";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
+import useSWR from "swr";
-import { TeamPlanQuota } from "@/config/team";
import {
getBotName,
getCountryName,
@@ -20,7 +20,7 @@ import {
getRegionName,
} from "@/lib/contries";
import { DATE_DIMENSION_ENUMS } from "@/lib/enums";
-import { isLink, removeUrlSuffix } from "@/lib/utils";
+import { fetcher, isLink, removeUrlSuffix } from "@/lib/utils";
import { useElementSize } from "@/hooks/use-element-size";
import { Button } from "@/components/ui/button";
import {
@@ -179,6 +179,11 @@ export function DailyPVUVChart({
const t = useTranslations("Components");
+ const { data: plan } = useSWR<{ slAnalyticsRetention: number }>(
+ `/api/plan?team=${user.team}`,
+ fetcher,
+ );
+
const processedData = processUrlMeta(data).map((entry) => ({
date: entry.date,
pv: entry.clicks,
@@ -254,40 +259,39 @@ export function DailyPVUVChart({
-
+ {plan && (
+
+ )}
{["pv", "uv"].map((key) => {
const chart = key as keyof typeof chartConfig;
return (
diff --git a/app/(protected)/dashboard/urls/meta.tsx b/app/(protected)/dashboard/urls/meta.tsx
index 9e6806d..c68dfb7 100644
--- a/app/(protected)/dashboard/urls/meta.tsx
+++ b/app/(protected)/dashboard/urls/meta.tsx
@@ -5,7 +5,6 @@ import { UrlMeta, User } from "@prisma/client";
import { useTranslations } from "next-intl";
import useSWR from "swr";
-import { TeamPlanQuota } from "@/config/team";
import { DATE_DIMENSION_ENUMS } from "@/lib/enums";
import { fetcher } from "@/lib/utils";
import {
@@ -37,6 +36,11 @@ export default function UserUrlMetaInfo({ user, action, urlId }: UrlMetaProps) {
{ focusThrottleInterval: 30000 }, // 30 seconds,
);
+ const { data: plan } = useSWR<{ slAnalyticsRetention: number }>(
+ `/api/plan?team=${user.team}`,
+ fetcher,
+ );
+
if (isLoading)
return (
@@ -55,40 +59,39 @@ export default function UserUrlMetaInfo({ user, action, urlId }: UrlMetaProps) {
"",
)}
.
-
+ {plan && (
+
+ )}
);
diff --git a/app/(protected)/dashboard/urls/url-list.tsx b/app/(protected)/dashboard/urls/url-list.tsx
index d56332b..d0dd340 100644
--- a/app/(protected)/dashboard/urls/url-list.tsx
+++ b/app/(protected)/dashboard/urls/url-list.tsx
@@ -410,7 +410,7 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
setShowForm(!isShowForm);
}}
>
-
{t("Edit")}
+
{t("Edit")}
diff --git a/components/layout/site-footer.tsx b/components/layout/site-footer.tsx
index f63d1d5..7d63d02 100644
--- a/components/layout/site-footer.tsx
+++ b/components/layout/site-footer.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
import Link from "next/link";
-import { version } from "package.json";
+import pkg from "package.json";
import { footerLinks, siteConfig } from "@/config/site";
import { cn } from "@/lib/utils";
@@ -76,7 +76,7 @@ export function SiteFooter({ className }: React.HTMLAttributes) {
rel="noreferrer"
className="font-thin underline-offset-2 hover:underline"
>
- v{version}
+ v{pkg.version}
diff --git a/components/sections/pricing.tsx b/components/sections/pricing.tsx
index d3fde69..a8e2c5b 100644
--- a/components/sections/pricing.tsx
+++ b/components/sections/pricing.tsx
@@ -6,68 +6,74 @@ import Link from "next/link";
import { motion } from "framer-motion";
import { X } from "lucide-react";
import { useTranslations } from "next-intl";
+import useSWR from "swr";
-import { TeamPlanQuota } from "@/config/team";
-import { cn, nFormatter } from "@/lib/utils";
+import { PlanQuotaFormData } from "@/lib/dto/plan";
+import { cn, fetcher, nFormatter } from "@/lib/utils";
import { Icons } from "../shared/icons";
import { Button } from "../ui/button";
-const getBenefits = (plan) => [
+const getBenefits = (plan: PlanQuotaFormData) => [
{
- text: `${nFormatter(plan.SL_TrackedClicks)} tracked clicks/mo`,
+ text: `${nFormatter(plan.slTrackedClicks)} tracked clicks/mo`,
checked: true,
icon:
,
},
{
- text: `${nFormatter(plan.SL_NewLinks)} new links/mo`,
+ text: `${nFormatter(plan.slNewLinks)} new links/mo`,
checked: true,
icon:
,
},
{
- text: `${plan.SL_AnalyticsRetention}-day analytics retention`,
+ text: `${plan.slAnalyticsRetention}-day analytics retention`,
checked: true,
icon:
,
},
{
text: `Customize short link QR code`,
- checked: plan.SL_CustomQrCodeLogo,
+ checked: plan.slCustomQrCodeLogo,
icon:
,
},
{
- text: `${nFormatter(plan.EM_EmailAddresses)} email addresses/mo`,
+ text: `${nFormatter(plan.emEmailAddresses)} email addresses/mo`,
checked: true,
icon:
,
},
{
- text: `${nFormatter(plan.EM_SendEmails)} send emails/mo`,
+ text: `${nFormatter(plan.emSendEmails)} send emails/mo`,
checked: true,
icon:
,
},
{
- text: `${plan.SL_Domains === 1 ? "One" : plan.SL_Domains} domain${plan.SL_Domains > 1 ? "s" : ""}`,
+ text: `${plan.slDomains === 1 ? "One" : plan.slDomains} domain${plan.slDomains > 1 ? "s" : ""}`,
checked: true,
icon:
,
},
{
text: "Advanced analytics",
- checked: plan.SL_AdvancedAnalytics,
+ checked: plan.slAdvancedAnalytics,
icon:
,
},
{
- text: `${plan.APP_Support.charAt(0).toUpperCase() + plan.APP_Support.slice(1)} support`,
+ text: `${plan.appSupport.charAt(0).toUpperCase() + plan.appSupport.slice(1)} support`,
checked: true,
icon:
,
},
{
text: "Open API Access",
- checked: plan.APP_ApiAccess,
+ checked: plan.appApiAccess,
icon:
,
},
];
export const PricingSection = () => {
const t = useTranslations("Landing");
+ const { data: plan } = useSWR<{
+ total: number;
+ list: PlanQuotaFormData[];
+ }>(`/api/plan?all=1`, fetcher);
+
return (