Skip to content

Commit

Permalink
OK
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury1093 committed Dec 12, 2023
1 parent 960176d commit 80e4ebb
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 124 deletions.
10 changes: 3 additions & 7 deletions src/components/ApiUsage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Capacity, Loading, Spacer, Text } from "@geist-ui/react";
import { Loader } from "@geist-ui/react-icons";
import { format, parseISO } from "date-fns";
import React, { useEffect, useState } from "react";

import { sentryException } from "@/util/sentry";
Expand All @@ -9,6 +8,7 @@ import { getApiUsageClient } from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";
import styles from "./ApiUsage.module.css";
import { Demo } from "./Demo";
import { formatDate } from "@/util/helpers";

export function ApiUsage(): React.ReactElement {
const { subscription, user, userFinishedLoading } = useUser();
Expand All @@ -18,7 +18,7 @@ export function ApiUsage(): React.ReactElement {
if (!user || !userFinishedLoading) {
return;
}
getApiUsageClient(user, subscription)
getApiUsageClient(subscription)
.then(setApiCalls)
.catch(sentryException);
}, [user, userFinishedLoading, subscription]);
Expand Down Expand Up @@ -62,14 +62,10 @@ export function ApiUsage(): React.ReactElement {
<Spacer />
<Demo
onVerified={() =>
getApiUsageClient(user, subscription).then(setApiCalls)
getApiUsageClient(subscription).then(setApiCalls)
}
/>
<Spacer />
</section>
);
}

function formatDate(d: string | Date): string {
return format(typeof d === "string" ? parseISO(d) : d, "do MMM yyyy");
}
35 changes: 19 additions & 16 deletions src/components/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
productName,
SAAS_10K_PRODUCT_ID,
} from "@/util/subs";
import { SupabaseProductWithPrice } from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";
import { ApiUsage } from "./ApiUsage";
import styles from "./Dashboard.module.css";
import { ProductWithPrice } from "@/supabase/domain.types";
import { formatDate } from "@/util/helpers";

interface DashboardProps {
products: SupabaseProductWithPrice[];
products: ProductWithPrice[];
}

export function Dashboard({ products }: DashboardProps): React.ReactElement {
Expand All @@ -40,13 +41,27 @@ export function Dashboard({ products }: DashboardProps): React.ReactElement {
<Page>
<section className={styles.plan}>
<div>
<Spacer y={2} />
<Text h2>Hello{userDetails?.full_name || ""},</Text>
<Text p>
Thanks for using the Reacher{" "}
{productName(subscription?.prices?.products)}!
</Text>
<div className="flex">
<StripeMananageButton>Billing History</StripeMananageButton>
</div>
<div>
<Text className="text-right" p>
Active Subscription
</Text>
<Text className="text-right" h3>
{productName(subscription?.prices?.products)}
</Text>
{subscription?.cancel_at && (
<Text p small em className="text-right mt-0">
⚠️ Plan ends on{" "}
{formatDate(new Date(subscription.cancel_at))}
</Text>
)}
<div className="text-right">
{subscription ? (
<StripeMananageButton>
Manage Subscription
Expand All @@ -60,20 +75,8 @@ export function Dashboard({ products }: DashboardProps): React.ReactElement {
<strong>Upgrade Plan</strong>
</GLink>
)}
<Spacer />
<StripeMananageButton>
Billing History
</StripeMananageButton>
</div>
</div>
<div>
<Text className="text-right" p>
Active Subscription
</Text>
<Text className="text-right" h3>
{productName(subscription?.prices?.products)}
</Text>
</div>
</section>

<Spacer y={3} />
Expand Down
14 changes: 6 additions & 8 deletions src/components/ProductCard/Sub.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@ import { postData } from "@/util/helpers";
import { sentryException } from "@/util/sentry";
import { getStripe } from "@/util/stripeClient";
import { COMMERCIAL_LICENSE_PRODUCT_ID } from "@/util/subs";
import type {
SupabasePrice,
SupabaseProductWithPrice,
} from "@/util/supabaseClient";
import type {} from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";
import { Card } from "./Card";
import styles from "./Card.module.css";
import { Tables } from "@/supabase/database.types";
import { ProductWithPrice } from "@/supabase/domain.types";

export interface ProductCardProps {
currency: string;
product: SupabaseProductWithPrice;
product: ProductWithPrice;
subscription: Tables<"subscriptions"> | null;
}

Expand All @@ -37,7 +35,7 @@ export function ProductCard({
return <p>Error: No price found for product {product.id}.</p>;
}

const handleCheckout = async (price: SupabasePrice) => {
const handleCheckout = async (price: Tables<"prices">) => {
setPriceIdLoading(price.id);

if (!session) {
Expand Down Expand Up @@ -69,7 +67,7 @@ export function ProductCard({

const priceString = new Intl.NumberFormat("en-US", {
style: "currency",
currency: price.currency,
currency: price.currency || undefined,
minimumFractionDigits: 0,
}).format(price.unit_amount / 100);

Expand Down Expand Up @@ -155,7 +153,7 @@ export function ProductCard({
</span>
)
}
title={product.name}
title={product.name || "No Product Name"} // Latter should never happen
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/api/stripe/create-checkout-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { NextApiRequest, NextApiResponse } from "next";
import { getWebappURL } from "@/util/helpers";
import { sentryException } from "@/util/sentry";
import { stripe } from "@/util/stripeServer";
import { SupabasePrice } from "@/util/supabaseClient";
import { getActiveSubscription, getUser } from "@/util/supabaseServer";
import { createOrRetrieveCustomer } from "@/util/useDatabase";
import { Tables } from "@/supabase/database.types";

const createCheckoutSession = async (
req: NextApiRequest,
Expand All @@ -24,7 +24,7 @@ const createCheckoutSession = async (
quantity = 1,
metadata = {},
} = req.body as {
price: SupabasePrice;
price: Tables<"prices">;
quantity: number;
metadata: Record<string, string>;
};
Expand Down
4 changes: 2 additions & 2 deletions src/pages/api/v0/check_email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import dns from "dns/promises";
import { checkUserInDB, cors, removeSensitiveData } from "@/util/api";
import { updateSendinblue } from "@/util/sendinblue";
import { sentryException } from "@/util/sentry";
import { SupabaseCall } from "@/util/supabaseClient";
import { supabaseAdmin } from "@/util/supabaseServer";
import { Tables } from "@/supabase/database.types";

const TIMEOUT = 50000;
const MAX_PRIORITY = 5; // Higher is faster, 5 is max.
Expand Down Expand Up @@ -74,7 +74,7 @@ const POST = async (

// Add to supabase
const response = await supabaseAdmin
.from<SupabaseCall>("calls")
.from<Tables<"calls">>("calls")
.insert({
endpoint: "/v0/check_email",
user_id: user.id,
Expand Down
10 changes: 4 additions & 6 deletions src/pages/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import React, { useEffect } from "react";

import { Dashboard, Nav } from "../components";
import { sentryException } from "@/util/sentry";
import {
getActiveProductsWithPrices,
SupabaseProductWithPrice,
} from "@/util/supabaseClient";
import { getActiveProductWithPrices } from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";
import { ProductWithPrice } from "@/supabase/domain.types";

export const getStaticProps: GetStaticProps = async () => {
const products = await getActiveProductsWithPrices();
const products = await getActiveProductWithPrices();

return {
props: {
Expand All @@ -22,7 +20,7 @@ export const getStaticProps: GetStaticProps = async () => {
};

interface IndexProps {
products: SupabaseProductWithPrice[];
products: ProductWithPrice[];
}

export default function Index({ products }: IndexProps): React.ReactElement {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { useState } from "react";
import { Nav } from "../components";
import { parseHashComponents, postData } from "@/util/helpers";
import { sentryException } from "@/util/sentry";
import { getActiveProductsWithPrices } from "@/util/supabaseClient";
import { getActiveProductWithPrices } from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";

export const getStaticProps: GetStaticProps = async () => {
const products = await getActiveProductsWithPrices();
const products = await getActiveProductWithPrices();

return {
props: {
Expand Down
10 changes: 4 additions & 6 deletions src/pages/pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import {
COMMERCIAL_LICENSE_PRODUCT_ID,
SAAS_10K_PRODUCT_ID,
} from "@/util/subs";
import {
getActiveProductsWithPrices,
SupabaseProductWithPrice,
} from "@/util/supabaseClient";
import { getActiveProductWithPrices } from "@/util/supabaseClient";
import { useUser } from "@/util/useUser";
import { ProductWithPrice } from "@/supabase/domain.types";

export const getStaticProps: GetStaticProps = async () => {
const products = await getActiveProductsWithPrices();
const products = await getActiveProductWithPrices();

return {
props: {
Expand All @@ -24,7 +22,7 @@ export const getStaticProps: GetStaticProps = async () => {
};

interface PricingProps {
products: SupabaseProductWithPrice[];
products: ProductWithPrice[];
}

export default function Pricing({
Expand Down
4 changes: 4 additions & 0 deletions src/supabase/domain.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ export interface PriceWithProduct extends Tables<"prices"> {
export interface SubscriptionWithPrice extends Tables<"subscriptions"> {
prices: PriceWithProduct;
}

export interface ProductWithPrice extends Tables<"products"> {
prices: PriceWithProduct[];
}
5 changes: 5 additions & 0 deletions src/util/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios, { AxiosError, AxiosResponse } from "axios";
import retry from "async-retry";
import { format, parseISO } from "date-fns";

// Gets the currently depoloyed URL.
export const getWebappURL = (): string => {
Expand Down Expand Up @@ -98,3 +99,7 @@ export function parseHashComponents(hash: string): Record<string, string> {
return acc;
}, {} as Record<string, string>);
}

export function formatDate(d: string | Date): string {
return format(typeof d === "string" ? parseISO(d) : d, "do MMM yyyy");
}
2 changes: 1 addition & 1 deletion src/util/sendinblue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function sendinblueDateFormat(d: Date): string {
*/
export async function updateSendinblue(
userId: string,
sendinblueContactId?: string
sendinblueContactId: string | null
): Promise<void> {
if (!sendinblueContactId) {
throw new Error(
Expand Down
6 changes: 3 additions & 3 deletions src/util/subs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SupabaseProduct } from "./supabaseClient";
import { Tables } from "@/supabase/database.types";
import { SubscriptionWithPrice } from "@/supabase/domain.types";

// We're hardcoding these as env variables.
Expand All @@ -13,11 +13,11 @@ if (!SAAS_10K_PRODUCT_ID || !COMMERCIAL_LICENSE_PRODUCT_ID) {
}

// Get the user-friendly name of a product.
export function productName(product?: SupabaseProduct): string {
export function productName(product?: Tables<"products">): string {
return product?.name || "Free Trial";
}

// Return the max monthly calls
export function subApiMaxCalls(sub: SubscriptionWithPrice | undefined): number {
export function subApiMaxCalls(sub: SubscriptionWithPrice | null): number {
return sub?.prices?.products?.id === SAAS_10K_PRODUCT_ID ? 10000 : 50;
}
Loading

0 comments on commit 80e4ebb

Please sign in to comment.