feat: separate subscription from payment (#104)

* feat: use connection pooling

* chore: minor subscription change

* feat: separate subscription from payment
This commit is contained in:
Tianzhou (天舟)
2023-05-21 20:34:33 +08:00
committed by GitHub
parent 86c6abe24c
commit 9287da7407
12 changed files with 195 additions and 100 deletions

View File

@ -1,13 +1,15 @@
import { signIn, useSession } from "next-auth/react";
import Link from "next/link";
import { useTranslation } from "react-i18next";
import SubscriptionHistoryTable from "./SubscriptionHistoryTable";
import PaymentHistoryTable from "./PaymentHistoryTable";
import { getDateString } from "@/utils";
const AccountView = () => {
const { t } = useTranslation();
const { data: session } = useSession();
const expired = session?.user?.subscription?.expireAt && session?.user?.subscription?.expireAt < Date.now();
return (
<>
{!session && (
@ -38,6 +40,11 @@ const AccountView = () => {
</Link>
</div>
<div className="flex text-base font-semibold tracking-tight items-center">
{!!expired && (
<span className="mr-2 rounded-full bg-yellow-50 px-3 py-1 font-medium text-yellow-700 ring-1 ring-inset ring-yellow-600/20">
{t("setting.plan.expired")}
</span>
)}
<span
className={`${
session?.user.subscription.plan == "PRO"
@ -61,7 +68,7 @@ const AccountView = () => {
)}
</div>
</div>
<SubscriptionHistoryTable />
<PaymentHistoryTable />
</div>
)}
</>

View File

@ -2,18 +2,18 @@ import axios from "axios";
import { t } from "i18next";
import { useSession } from "next-auth/react";
import { useEffect, useState } from "react";
import { SubscriptionPurchase } from "@/types";
import { Payment } from "@/types";
import { getCurrencySymbol, getDateString } from "@/utils";
const SubscriptionHistoryTable = () => {
const [list, setList] = useState<SubscriptionPurchase[]>([]);
const PaymentHistoryTable = () => {
const [list, setList] = useState<Payment[]>([]);
const { data: session } = useSession();
useEffect(() => {
const refreshSubscriptionList = async (userId: string) => {
let list: SubscriptionPurchase[] = [];
const refreshPaymentList = async (userId: string) => {
let list: Payment[] = [];
try {
const { data } = await axios.get("/api/subscription", {
const { data } = await axios.get("/api/payment", {
headers: { Authorization: `Bearer ${userId}` },
});
list = data;
@ -24,7 +24,7 @@ const SubscriptionHistoryTable = () => {
};
if (session?.user.id) {
refreshSubscriptionList(session.user.id);
refreshPaymentList(session.user.id);
}
}, [session]);
@ -53,18 +53,18 @@ const SubscriptionHistoryTable = () => {
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
{list.map((subscription) => (
<tr key={subscription.id}>
{list.map((payment) => (
<tr key={payment.id}>
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">
{getDateString(subscription.createdAt)}
{getDateString(payment.createdAt)}
</td>
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{subscription.description}</td>
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{payment.description}</td>
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
{getCurrencySymbol(subscription.currency.toLocaleUpperCase())}
{subscription.amount / 100}
{getCurrencySymbol(payment.currency.toLocaleUpperCase())}
{payment.amount / 100}
</td>
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
<a href={subscription.receipt} target="_blank" className="text-indigo-600 hover:text-indigo-900">
<a href={payment.receipt} target="_blank" className="text-indigo-600 hover:text-indigo-900">
{t("setting.subscription.view-receipt")}
</a>
</td>
@ -79,4 +79,4 @@ const SubscriptionHistoryTable = () => {
);
};
export default SubscriptionHistoryTable;
export default PaymentHistoryTable;

View File

@ -36,15 +36,15 @@ const SettingGeneralView = () => {
</div>
)}
{hasFeature("account") && (
{hasFeature("payment") && (
<div className="w-full border border-gray-200 dark:border-zinc-700 p-4 rounded-lg space-y-2">
<AccountView />
<PricingView />
</div>
)}
{hasFeature("payment") && session?.user?.subscription.plan != "PRO" && (
{hasFeature("account") && (
<div className="w-full border border-gray-200 dark:border-zinc-700 p-4 rounded-lg space-y-2">
<PricingView />
<AccountView />
</div>
)}