This commit is contained in:
Karol Wypchlo 2021-03-03 15:43:46 +01:00
parent c2f4254249
commit 21aa045d2a
2 changed files with 40 additions and 19 deletions

View File

@ -1,5 +1,12 @@
{ {
"sub": "ab776d6d-f324-4fa7-a728-7587d5215481", "firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"sub": "ab776d6d-f324-4fa7-4k21-7587d5215481",
"tier": 1, "tier": 1,
"subscribedUntil": "0001-01-01T00:00:00Z" "subscribedUntil": "0001-01-01T00:00:00Z",
"subscriptionStatus": "active",
"subscriptionCancelAt": "2021-04-21T00:00:00Z",
"subscriptionCancelAtPeriodEnd": true,
"stripeCustomerId": "cus_J0iYnAp6LRgsTI"
} }

View File

@ -1,3 +1,4 @@
import dayjs from "dayjs";
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import useSWR from "swr"; import useSWR from "swr";
import { useEffect } from "react"; import { useEffect } from "react";
@ -5,9 +6,17 @@ import ky from "ky/umd";
import { useState } from "react"; import { useState } from "react";
const plans = [ const plans = [
{ id: "initial_free", stripe: null, name: "Free", price: 0, description: "Unlimited bandwidth with throttled speed" }, {
id: "initial_free",
tier: 1,
stripe: null,
name: "Free",
price: 0,
description: "Unlimited bandwidth with throttled speed",
},
{ {
id: "initial_plus", id: "initial_plus",
tier: 2,
stripe: "price_1IO6FpIzjULiPWN6XHIG5mU9", stripe: "price_1IO6FpIzjULiPWN6XHIG5mU9",
name: "Skynet Plus", name: "Skynet Plus",
price: 5, price: 5,
@ -15,6 +24,7 @@ const plans = [
}, },
{ {
id: "initial_pro", id: "initial_pro",
tier: 3,
stripe: "price_1IO6FpIzjULiPWN6xYjmUuGb", stripe: "price_1IO6FpIzjULiPWN6xYjmUuGb",
name: "Skynet Pro", name: "Skynet Pro",
price: 20, price: 20,
@ -22,6 +32,7 @@ const plans = [
}, },
{ {
id: "initial_extreme", id: "initial_extreme",
tier: 4,
stripe: "price_1IO6FpIzjULiPWN636iFN02j", stripe: "price_1IO6FpIzjULiPWN636iFN02j",
name: "Skynet Extreme", name: "Skynet Extreme",
price: 80, price: 80,
@ -30,6 +41,7 @@ const plans = [
]; ];
const fetcher = (url) => fetch(url).then((r) => r.json()); const fetcher = (url) => fetch(url).then((r) => r.json());
const apiPrefix = process.env.NODE_ENV === "development" ? "/api/stubs" : "";
const ActiveBadge = () => { const ActiveBadge = () => {
return ( return (
@ -40,11 +52,9 @@ const ActiveBadge = () => {
}; };
export default function Payments() { export default function Payments() {
const { data: user } = useSWR("/user", fetcher); const { data: user } = useSWR(`${apiPrefix}/user`, fetcher);
const { data: subscription } = useSWR("/api/stripe/subscription", fetcher); const [selectedPlan, setSelectedPlan] = useState(plans[0]);
const [selectedPlanId, setSelectedPlanId] = useState("initial_free"); const activePlan = plans.find(({ tier }) => user?.tier === tier);
const [activePlanId, setActivePlanId] = useState(null);
const selectedPlan = plans.find(({ id }) => selectedPlanId === id);
const handleSubscribe = async () => { const handleSubscribe = async () => {
try { try {
const price = selectedPlan.stripe; const price = selectedPlan.stripe;
@ -56,12 +66,6 @@ export default function Payments() {
} }
}; };
useEffect(() => {
const plan = plans.find(({ stripe }) => subscription?.plan?.id === stripe);
setActivePlanId(plan);
}, [subscription, setActivePlanId]);
return ( return (
<Layout title="Payments"> <Layout title="Payments">
<div className="bg-white rounded-lg shadow px-5 py-6 sm:px-6"> <div className="bg-white rounded-lg shadow px-5 py-6 sm:px-6">
@ -77,8 +81,17 @@ export default function Payments() {
<div className="bg-white overflow-hidden shadow rounded-lg"> <div className="bg-white overflow-hidden shadow rounded-lg">
<div className="px-4 py-5 sm:p-6"> <div className="px-4 py-5 sm:p-6">
<dt className="text-sm font-medium text-gray-500 truncate">Subscription status</dt> <dt className="text-sm font-medium text-gray-500 truncate">Subscription status</dt>
<dd className="mt-1 text-3xl font-semibold text-gray-900 capitalize">{subscription?.status ?? "—"}</dd> <dd className="mt-1 text-3xl font-semibold text-gray-900 capitalize">
{user?.subscriptionStatus ?? "—"}
</dd>
</div> </div>
{user?.subscriptionCancelAtPeriodEnd && (
<div className="bg-gray-50 px-4 py-4 sm:px-6">
<div className="text-sm">
Your plan will be cancelled on {dayjs(user.subscriptionCancelAt).format("D MMM YYYY")}.
</div>
</div>
)}
</div> </div>
{/* <div className="flex flex-col bg-white overflow-hidden shadow rounded-lg"> {/* <div className="flex flex-col bg-white overflow-hidden shadow rounded-lg">
@ -112,6 +125,7 @@ export default function Payments() {
<div className="text-sm">All paid up!</div> <div className="text-sm">All paid up!</div>
</div> </div>
</div> */} </div> */}
<div className="bg-white overflow-hidden shadow rounded-lg"> <div className="bg-white overflow-hidden shadow rounded-lg">
<div className="px-4 py-5 sm:p-6"> <div className="px-4 py-5 sm:p-6">
<dt className="text-sm font-medium text-gray-500 truncate">asdas</dt> <dt className="text-sm font-medium text-gray-500 truncate">asdas</dt>
@ -149,11 +163,11 @@ export default function Payments() {
type="radio" type="radio"
className="h-4 w-4 text-orange-500 cursor-pointer focus:ring-gray-900 border-gray-300" className="h-4 w-4 text-orange-500 cursor-pointer focus:ring-gray-900 border-gray-300"
aria-describedby="plan-option-pricing-0 plan-option-limit-0" aria-describedby="plan-option-pricing-0 plan-option-limit-0"
checked={plan.id === selectedPlanId} checked={plan === selectedPlan}
onChange={() => console.log(plan.id) || setSelectedPlanId(plan.id)} onChange={() => console.log(plan.name) || setSelectedPlan(plan)}
/> />
<span className="ml-3 font-medium text-gray-900">{plan.name}</span> <span className="ml-3 font-medium text-gray-900">{plan.name}</span>
{activePlanId === plan.id && <ActiveBadge />} {activePlan === plan && <ActiveBadge />}
</label> </label>
<p id="plan-option-pricing-0" className="ml-6 pl-1 text-sm md:ml-0 md:pl-0 md:text-center"> <p id="plan-option-pricing-0" className="ml-6 pl-1 text-sm md:ml-0 md:pl-0 md:text-center">
{/* On: "text-orange-900", Off: "text-gray-900" */} {/* On: "text-orange-900", Off: "text-gray-900" */}
@ -175,7 +189,7 @@ export default function Payments() {
<button <button
type="button" type="button"
onClick={handleSubscribe} onClick={handleSubscribe}
disabled={activePlanId === selectedPlanId} disabled={activePlan === selectedPlan}
className="bg-green-800 disabled:bg-gray-300 disabled:text-gray-400 border border-transparent rounded-md shadow-sm py-2 px-4 inline-flex justify-center text-sm font-medium text-white hover:bg-green-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-900" className="bg-green-800 disabled:bg-gray-300 disabled:text-gray-400 border border-transparent rounded-md shadow-sm py-2 px-4 inline-flex justify-center text-sm font-medium text-white hover:bg-green-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-900"
> >
Subscribe Subscribe