fix: replace /stripe/subscription requests

This commit is contained in:
phamhieu authored and Hieu Pham committed 2022-03-31 16:47:53 +07:00
1 parent d3676710f9
commit 028a8a093f
6 files changed
+39 -167

No files matched your search

@@ -12,4 +12,5 @@ export interface StripeProduct {
name: string
prod_id: string
unit_amount: number
supabase_prod_id: string
}
@@ -1,14 +1,11 @@
import Link from 'next/link'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import { FC, useState, useEffect } from 'react'
import { FC, useEffect } from 'react'
import { IconChevronRight, IconLoader } from '@supabase/ui'
import { useStore } from 'hooks'
import { API_URL } from 'lib/constants'
import { post } from 'lib/common/fetch'
import { useProjectSubscription, useStore } from 'hooks'
import Panel from 'components/to-be-cleaned/Panel'
import { StripeSubscription } from 'components/interfaces/Billing'
dayjs.extend(utc)
@@ -18,35 +15,19 @@ interface ProjectSummaryProps {
const ProjectSummary: FC<ProjectSummaryProps> = ({ project }) => {
const { ui } = useStore()
const [loading, setLoading] = useState(false)
const [subscription, setSubscription] = useState<StripeSubscription>()
const { subscription, isLoading: loading, error } = useProjectSubscription(project.ref)
const currentPeriodStart = subscription?.billing?.current_period_start ?? 0
const currentPeriodEnd = subscription?.billing?.current_period_end ?? 0
useEffect(() => {
getSubscription()
}, [])
const getSubscription = async () => {
try {
setLoading(true)
const { data: subscription, error }: { data: StripeSubscription; error: any } = await post(
`${API_URL}/stripe/subscription`,
{ subscription_id: project.subscription_id }
)
if (error) throw error
setSubscription(subscription)
} catch (error: any) {
if (error) {
ui.setNotification({
category: 'error',
message: `Failed to get project subscription: ${error.message}`,
message: `Failed to get project subscription: ${error?.message ?? 'unknown'}`,
})
} finally {
setLoading(false)
}
}
}, [error])
return (
<div className="w-full px-6 py-3 flex items-center">
+14 -71
View File
@@ -2,8 +2,8 @@ import React, { FC, useEffect, useState } from 'react'
import useSWR from 'swr'
import { Loading, Typography } from '@supabase/ui'
import { useStore } from 'hooks'
import { API_URL } from 'lib/constants'
import { useProjectSubscription, useStore } from 'hooks'
import { API_URL, PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
import { get, post } from 'lib/common/fetch'
import SparkBar from 'components/ui/SparkBar'
@@ -193,45 +193,19 @@ const usageLimits = {
const ProjectUsage: FC<any> = ({ projectRef, subscription_id }) => {
const { ui } = useStore()
const { data: stats, error: usageError } = useSWR(`${API_URL}/projects/${projectRef}/usage`, get)
const [loading, setLoading] = useState<boolean>(false)
const [error, setError] = useState<any>(null)
const [subscription, setSubscription] = useState<any>(null)
const { subscription, isLoading: loading, error } = useProjectSubscription(projectRef)
useEffect(() => {
let cancel = false
/**
* Get subscription information to decide
*/
const getSubscription = async () => {
try {
setLoading(true)
setError(null)
const { data, error } = await post(`${API_URL}/stripe/subscription`, {
subscription_id: subscription_id,
})
if (!cancel) setSubscription(data)
if (error) throw error
} catch (error: any) {
ui.setNotification({
category: 'error',
message: `Failed to get subscription: ${error.message}`,
})
if (!cancel) setError(error)
} finally {
if (!cancel) setLoading(false)
}
if (error) {
ui.setNotification({
category: 'error',
message: `Failed to get project subscription: ${error?.message ?? 'unknown'}`,
})
}
}, [error])
getSubscription()
return () => {
cancel = true
}
}, [subscription_id])
const tier = subscription && subscription.tier.unit_amount > 0 ? 'pro' : 'free'
const tier =
subscription?.tier?.supabase_prod_id === PRICING_TIER_PRODUCT_IDS.PRO ? 'pro' : 'free'
return (
<Loading active={loading}>
@@ -296,41 +270,10 @@ export default ProjectUsage
export const ProjectUsageMinimal: FC<any> = ({ projectRef, subscription_id, filter }) => {
const { data: stats, error: usageError } = useSWR(`${API_URL}/projects/${projectRef}/usage`, get)
const { subscription, isLoading: loading, error } = useProjectSubscription(projectRef)
const [loading, setLoading] = useState<boolean>(false)
const [error, setError] = useState<any>(null)
const [subscription, setSubscription] = useState<any>(null)
useEffect(() => {
let cancel = false
/**
* Get subscription information to decide
*/
const getSubscription = async () => {
try {
setLoading(true)
setError(null)
const { data, error } = await post(`${API_URL}/stripe/subscription`, {
subscription_id: subscription_id,
})
if (!cancel) setSubscription(data)
if (error) throw error
} catch (error: any) {
if (!cancel) setError(error)
} finally {
if (!cancel) setLoading(false)
}
}
getSubscription()
return () => {
cancel = true
}
}, [subscription_id])
const tier = subscription && subscription.tier.unit_amount > 0 ? 'pro' : 'free'
const tier =
subscription?.tier?.supabase_prod_id === PRICING_TIER_PRODUCT_IDS.PRO ? 'pro' : 'free'
return (
<Loading active={loading}>
+2
View File
@@ -3,3 +3,5 @@ export * from './useOrganizationDetail'
export * from './useProfile'
export * from './useProjectAuthConfig'
export * from './useSubscriptionStats'
export * from './useProjectSubscription'
export * from './useProjectPaygStatistics'
+1
View File
@@ -28,6 +28,7 @@ export const PRICING_TIER_LABELS = {
export const PRICING_TIER_PRODUCT_IDS = {
FREE: 'tier_free',
PRO: 'tier_pro',
PAYG: 'tier_payg',
}
export const PRICING_TIER_FREE_KEY = 'FREE'
@@ -2,27 +2,12 @@ import dayjs from 'dayjs'
import { FC, useEffect, useState } from 'react'
import { observer } from 'mobx-react-lite'
import { Typography, Loading, IconArrowRight } from '@supabase/ui'
import { get as _get, maxBy } from 'lodash'
import { Dictionary } from '@supabase/grid'
import { useStore, withAuth } from 'hooks'
import { post, get } from 'lib/common/fetch'
import {
API_URL,
DATE_FORMAT,
STRIPE_PRODUCT_IDS,
TIME_PERIODS_REPORTS,
TIME_PERIODS_BILLING,
} from 'lib/constants'
import { useProjectPaygStatistics, useProjectSubscription, useStore, withAuth } from 'hooks'
import { STRIPE_PRODUCT_IDS, TIME_PERIODS_REPORTS, TIME_PERIODS_BILLING } from 'lib/constants'
import { SettingsLayout } from 'components/layouts'
import LoadingUI from 'components/ui/Loading'
import {
PAYGUsage,
Subscription,
StripeSubscription,
chargeableProducts,
Invoices,
} from 'components/interfaces/Billing'
import { PAYGUsage, Subscription, Invoices } from 'components/interfaces/Billing'
import ProjectUsage from 'components/to-be-cleaned/Usage'
import DateRangePicker from 'components/to-be-cleaned/DateRangePicker'
@@ -50,66 +35,25 @@ type SettingsProps = {
}
const Settings: FC<SettingsProps> = ({ project }) => {
const { ui } = useStore()
const projectRef = ui.selectedProject?.ref
const [loading, setLoading] = useState<boolean>(true)
const [subscription, setSubscription] = useState<StripeSubscription>()
const [paygStats, setPaygStats] = useState<Dictionary<number>>()
const {
subscription,
isLoading: loading,
error,
} = useProjectSubscription(ui.selectedProject?.ref)
const { paygStats } = useProjectPaygStatistics(
ui.selectedProject?.ref,
subscription?.tier?.supabase_prod_id
)
const [dateRange, setDateRange] = useState<any>()
useEffect(() => {
if (projectRef) {
getSubscription()
}
}, [projectRef])
const getSubscription = async () => {
try {
setLoading(true)
const { data: subscription, error }: { data: StripeSubscription; error: any } = await post(
`${API_URL}/stripe/subscription`,
{
subscription_id: project.subscription_id,
}
)
if (error) throw error
setSubscription(subscription)
if (subscription.tier.prod_id === STRIPE_PRODUCT_IDS.PAYG) {
fetchPaygStatistics()
}
} catch (error: any) {
if (error) {
ui.setNotification({
error,
category: 'error',
message: `Failed to get subscription: ${error.message}`,
message: `Failed to get project subscription: ${error?.message ?? 'unknown'}`,
})
} finally {
setLoading(false)
}
}
const fetchPaygStatistics = async () => {
const startDate = dayjs().utc().startOf('month').format(DATE_FORMAT)
const endDate = dayjs().utc().endOf('month').format(DATE_FORMAT)
const attributes =
'total_db_size_bytes,total_db_egress_bytes,total_storage_size_bytes,total_storage_egress'
const url = `${API_URL}/projects/${
project.ref
}/daily-stats?attribute=${attributes}&startDate=${encodeURIComponent(
startDate
)}&endDate=${encodeURIComponent(endDate)}&interval='1d'`
const { data } = await get(url)
const paygStats: any = {}
chargeableProducts.forEach((product: any) => {
product.features.forEach((feature: any) => {
paygStats[feature.attribute] = _get(maxBy(data, feature.attribute), feature.attribute)
})
})
setPaygStats(paygStats)
}
}, [error])
if (!subscription) {
return <LoadingUI />