diff --git a/packages/dashboard-v2/package.json b/packages/dashboard-v2/package.json
index 7b620128..7b561154 100644
--- a/packages/dashboard-v2/package.json
+++ b/packages/dashboard-v2/package.json
@@ -23,6 +23,7 @@
"@fontsource/source-sans-pro": "^4.5.3",
"classnames": "^2.3.1",
"copy-text-to-clipboard": "^3.0.1",
+ "dayjs": "^1.10.8",
"gatsby": "^4.6.2",
"gatsby-plugin-postcss": "^5.7.0",
"http-status-codes": "^2.2.0",
diff --git a/packages/dashboard-v2/src/components/Button/Button.js b/packages/dashboard-v2/src/components/Button/Button.js
index 165935a2..95ecbede 100644
--- a/packages/dashboard-v2/src/components/Button/Button.js
+++ b/packages/dashboard-v2/src/components/Button/Button.js
@@ -6,7 +6,7 @@ import styled from "styled-components";
*/
export const Button = styled.button.attrs(({ $primary }) => ({
type: "button",
- className: `px-6 py-3 rounded-full font-sans uppercase text-xs tracking-wide text-palette-600
+ className: `px-6 py-3 rounded-full font-sans uppercase text-xs tracking-wide text-palette-600 transition-[filter] hover:brightness-90
${$primary ? "bg-primary" : "bg-white border-2 border-black"}`,
}))``;
Button.propTypes = {
diff --git a/packages/dashboard-v2/src/components/CurrentPlan/CurrentPlan.js b/packages/dashboard-v2/src/components/CurrentPlan/CurrentPlan.js
new file mode 100644
index 00000000..c5cdee36
--- /dev/null
+++ b/packages/dashboard-v2/src/components/CurrentPlan/CurrentPlan.js
@@ -0,0 +1,50 @@
+import dayjs from "dayjs";
+import relativeTime from "dayjs/plugin/relativeTime";
+
+import { useUser } from "../../contexts/user";
+import useSubscriptionPlans from "../../hooks/useSubscriptionPlans";
+
+import LatestPayment from "./LatestPayment";
+import SuggestedPlan from "./SuggestedPlan";
+
+dayjs.extend(relativeTime);
+
+const CurrentPlan = () => {
+ const { user, error: userError } = useUser();
+ const { activePlan, plans, error: plansError } = useSubscriptionPlans(user);
+
+ if (!user || !activePlan) {
+ return (
+ // TODO: a nicer loading indicator
+
Loading...
+ );
+ }
+
+ if (userError || plansError) {
+ return (
+
+
An error occurred while loading this data.
+
We'll retry automatically.
+
+ );
+ }
+
+ return (
+
+
{activePlan.name}
+
+ {activePlan.price === 0 &&
100GB without paying a dime! 🎉
}
+ {activePlan.price !== 0 &&
+ (user.subscriptionCancelAtPeriodEnd ? (
+
Your subscription expires {dayjs(user.subscribedUntil).fromNow()}
+ ) : (
+
{dayjs(user.subscribedUntil).fromNow(true)} until the next payment
+ ))}
+
+
+
+
+ );
+};
+
+export default CurrentPlan;
diff --git a/packages/dashboard-v2/src/components/CurrentPlan/LatestPayment.js b/packages/dashboard-v2/src/components/CurrentPlan/LatestPayment.js
new file mode 100644
index 00000000..8ca2ab9e
--- /dev/null
+++ b/packages/dashboard-v2/src/components/CurrentPlan/LatestPayment.js
@@ -0,0 +1,18 @@
+import dayjs from "dayjs";
+
+// TODO: this is not an accurate information, we need this data from the backend
+const LatestPayment = ({ user }) => (
+
+
+ Latest payment
+
+ {dayjs(user.subscribedUntil).subtract(1, "month").format("MM/DD/YYYY")}
+
+
+
+ Success
+
+
+);
+
+export default LatestPayment;
diff --git a/packages/dashboard-v2/src/components/CurrentPlan/SuggestedPlan.js b/packages/dashboard-v2/src/components/CurrentPlan/SuggestedPlan.js
new file mode 100644
index 00000000..21aa9b48
--- /dev/null
+++ b/packages/dashboard-v2/src/components/CurrentPlan/SuggestedPlan.js
@@ -0,0 +1,24 @@
+import { Link } from "gatsby";
+import { useMemo } from "react";
+
+import { Button } from "../Button";
+
+const SuggestedPlan = ({ plans, activePlan }) => {
+ const nextPlan = useMemo(() => plans.find(({ tier }) => tier > activePlan.tier), [plans, activePlan]);
+
+ if (!nextPlan) {
+ return null;
+ }
+
+ return (
+
+
Discover {nextPlan.name}
+
{nextPlan.description}
+
+ Upgrade
+
+
+ );
+};
+
+export default SuggestedPlan;
diff --git a/packages/dashboard-v2/src/components/CurrentPlan/index.js b/packages/dashboard-v2/src/components/CurrentPlan/index.js
new file mode 100644
index 00000000..20390eab
--- /dev/null
+++ b/packages/dashboard-v2/src/components/CurrentPlan/index.js
@@ -0,0 +1,3 @@
+import CurrentPlan from "./CurrentPlan";
+
+export default CurrentPlan;
diff --git a/packages/dashboard-v2/src/hooks/useSubscriptionPlans.js b/packages/dashboard-v2/src/hooks/useSubscriptionPlans.js
new file mode 100644
index 00000000..26658df8
--- /dev/null
+++ b/packages/dashboard-v2/src/hooks/useSubscriptionPlans.js
@@ -0,0 +1,28 @@
+import { useEffect, useState } from "react";
+import useSWR from "swr";
+import freeTier from "../lib/tiers";
+
+export default function useSubscriptionPlans(user) {
+ const { data: paidPlans, error, mutate } = useSWR("stripe/prices");
+ const [plans, setPlans] = useState([freeTier]);
+ const [activePlan, setActivePlan] = useState(freeTier);
+
+ useEffect(() => {
+ if (paidPlans) {
+ setPlans((plans) => [...plans, ...paidPlans].sort((planA, planB) => planA.tier - planB.tier));
+ }
+ }, [paidPlans]);
+
+ useEffect(() => {
+ if (user) {
+ setActivePlan(plans.find((plan) => plan.tier === user.tier));
+ }
+ }, [plans, user]);
+
+ return {
+ error,
+ mutate,
+ plans,
+ activePlan,
+ };
+}
diff --git a/packages/dashboard-v2/src/lib/tiers.js b/packages/dashboard-v2/src/lib/tiers.js
new file mode 100644
index 00000000..82a5289f
--- /dev/null
+++ b/packages/dashboard-v2/src/lib/tiers.js
@@ -0,0 +1,9 @@
+const freeTier = {
+ id: "starter",
+ tier: 1,
+ name: "Free",
+ price: 0,
+ description: "100 GB - Casual user with a few files you want to access from around the world? Try the Free tier",
+};
+
+export default freeTier;
diff --git a/packages/dashboard-v2/src/pages/index.js b/packages/dashboard-v2/src/pages/index.js
index 593db528..695e6ac3 100644
--- a/packages/dashboard-v2/src/pages/index.js
+++ b/packages/dashboard-v2/src/pages/index.js
@@ -10,6 +10,7 @@ import DashboardLayout from "../layouts/DashboardLayout";
import Slider from "../components/Slider/Slider";
import CurrentUsage from "../components/CurrentUsage";
import Uploader from "../components/Uploader/Uploader";
+import CurrentPlan from "../components/CurrentPlan";
const IndexPage = () => {
const showRecentActivity = useMedia(`(min-width: ${theme.screens.md})`);
@@ -49,11 +50,7 @@ const IndexPage = () => {
}
className="h-[330px]"
>
-
- Current
- Plan
- Info
-
+
,
]}
/>
diff --git a/packages/dashboard-v2/yarn.lock b/packages/dashboard-v2/yarn.lock
index e860c61c..12ff2eb1 100644
--- a/packages/dashboard-v2/yarn.lock
+++ b/packages/dashboard-v2/yarn.lock
@@ -6296,6 +6296,11 @@ date-fns@^2.25.0:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2"
integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==
+dayjs@^1.10.8:
+ version "1.10.8"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.8.tgz#267df4bc6276fcb33c04a6735287e3f429abec41"
+ integrity sha512-wbNwDfBHHur9UOzNUjeKUOJ0fCb0a52Wx0xInmQ7Y8FstyajiV1NmK1e00cxsr9YrE9r7yAChE0VvpuY5Rnlow==
+
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"