From bd312b4f93413d6a19274e6add3f32cceeda66f1 Mon Sep 17 00:00:00 2001 From: John Yeo Date: Wed, 5 Feb 2025 17:41:18 +0000 Subject: [PATCH] working on demo --- frontend/package.json | 2 +- frontend/src/services/useAxiosSwr.tsx | 25 ++ .../src/utils/formatUtils/formatTextUtils.ts | 4 +- frontend/src/views/demo/DemoView.tsx | 213 ++++++++++-------- packages/react/package-lock.json | 4 +- packages/react/package.json | 2 +- packages/react/tsup.config.ts | 21 +- 7 files changed, 159 insertions(+), 112 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index e6b9d51c9..ffdbd722b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@autumn/shared": "*", - "@useautumn/react": "latest", + "@clerk/nextjs": "^6.9.14", "@fortawesome/fontawesome-svg-core": "^6.7.2", "@fortawesome/free-brands-svg-icons": "^6.7.2", diff --git a/frontend/src/services/useAxiosSwr.tsx b/frontend/src/services/useAxiosSwr.tsx index b0ad1eacc..baa50953c 100644 --- a/frontend/src/services/useAxiosSwr.tsx +++ b/frontend/src/services/useAxiosSwr.tsx @@ -1,6 +1,7 @@ import useSWR, { SWRConfiguration } from "swr"; import { useAxiosInstance } from "./useAxiosInstance"; import { AppEnv } from "@autumn/shared"; +import axios from "axios"; export function useAxiosSWR({ url, @@ -61,3 +62,27 @@ export function useAxiosPostSWR({ ...options, }); } + +export function useDemoSWR({ url, apiKey, options = {} }) { + const axiosInstance = axios.create({ + baseURL: "https://api.useautumn.com/v1", + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const fetcher = async (url: string) => { + try { + const res = await axiosInstance.get(url); + return res.data; + } catch (error) { + throw error; + } + }; + + return useSWR(url, fetcher, { + refreshInterval: 0, + revalidateOnFocus: false, + ...options, + }); +} diff --git a/frontend/src/utils/formatUtils/formatTextUtils.ts b/frontend/src/utils/formatUtils/formatTextUtils.ts index 4eeb5960d..c883fa455 100644 --- a/frontend/src/utils/formatUtils/formatTextUtils.ts +++ b/frontend/src/utils/formatUtils/formatTextUtils.ts @@ -1,5 +1,7 @@ export const keyToTitle = (key: string) => { - return key.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); + return key + .replace(/[_-]/g, " ") + .replace(/\b\w/g, (char) => char.toUpperCase()); }; export const keyToTitleFirstCaps = (key: string) => { diff --git a/frontend/src/views/demo/DemoView.tsx b/frontend/src/views/demo/DemoView.tsx index 2876f7ff0..356c431d4 100644 --- a/frontend/src/views/demo/DemoView.tsx +++ b/frontend/src/views/demo/DemoView.tsx @@ -1,21 +1,19 @@ "use client"; -import { useState, useEffect } from "react"; import axios from "axios"; -import SmallSpinner from "@/components/general/SmallSpinner"; -import { CustomToaster } from "@/components/general/CustomToaster"; import toast from "react-hot-toast"; -import { - Card, - CardHeader, - CardFooter, - CardContent, -} from "@/components/ui/card"; -import { Input } from "@/components/ui/input"; +import SmallSpinner from "@/components/general/SmallSpinner"; +import { useState, useEffect } from "react"; +import { CustomToaster } from "@/components/general/CustomToaster"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { LoaderCircle } from "lucide-react"; +import { AutumnProvider, PricingPage } from "@useautumn/react"; +import { useAxiosSWR, useDemoSWR } from "@/services/useAxiosSwr"; +import React from "react"; +import { keyToTitle } from "@/utils/formatUtils/formatTextUtils"; -const apiKey = "am_test_3ZNdjaDqtSXteFAB2qdvtrzP"; +const apiKey = "am_live_3ZavonZcha8ENdWwfHbrirU3"; const baseUrl = "https://api.useautumn.com/v1"; const headers = { Authorization: `Bearer ${apiKey}`, @@ -27,7 +25,7 @@ const axiosInstance = axios.create({ }); export default function DemoView() { - const customerId = "john"; + const customerId = "123"; const hasAccessRequest = { feature_id: "emails", @@ -44,62 +42,45 @@ export default function DemoView() { const [hasAccessResponse, setHasAccessResponse] = useState(null); const [sendEventLoading, setSendEventLoading] = useState(false); const [sendEventResponse, setSendEventResponse] = useState(null); - const [buyLoading, setBuyLoading] = useState(false); const [loading, setLoading] = useState(true); const [emailBalance, setEmailBalance] = useState(0); - const [quantities, setQuantities] = useState({ - enrichment: "", - ai: "", - }); - - const sendUsageUrl = "http://localhost:8080/v1/events"; - const [hasProFeatures, setHasProFeatures] = useState(false); - useEffect(() => { - const checkFeatures = async () => { - try { - const data = await checkAccess("pro-analytics"); - setHasProFeatures(data.allowed); - const emailData = await checkAccess("emails"); - setEmailBalance(emailData.balances[0].balance); - } catch (error) { - console.error("Error checking features access:", error); - setHasProFeatures(false); - setEmailBalance(0); - } - }; + const { data: customer, mutate: cusMutate } = useDemoSWR({ + url: `/customers/${customerId}`, + apiKey, + }); + console.log("Customer:", customer); + useEffect(() => { const init = async () => { setLoading(true); - await checkFeatures(); + // await checkFeatures(); setLoading(false); }; - init(); }, []); - //Attach Pro Plan to customer - const attachProduct = async () => { - const { data } = await axiosInstance.post("/attach", { - customer_id: customerId, - product_id: "pro", - }); + // //Attach Pro Plan to customer + // const attachProduct = async () => { + // const { data } = await axiosInstance.post("/attach", { + // customer_id: customerId, + // product_id: "pro", + // }); - if (data.checkout_url) { - window.open(data.checkout_url, "_blank"); - } else { - toast.success("Card already on file: automatically upgraded to Pro Plan"); - } - }; + // if (data.checkout_url) { + // window.open(data.checkout_url, "_blank"); + // } else { + // toast.success("Card already on file: automatically upgraded to Pro Plan"); + // } + // }; //Check access to Pro features and email balance const checkAccess = async (featureId: string) => { - const { data } = await axiosInstance.get( - `/entitled?customer_id=${customerId}&feature_id=${featureId}` - ); - - return data; + // const { data } = await axiosInstance.get( + // `/entitled?customer_id=${customerId}&feature_id=${featureId}` + // ); + // return data; }; //Send usage event for email @@ -115,23 +96,20 @@ export default function DemoView() { }; const handleClicked = async (eventName: string) => { - setHasAccessLoading(true); - const data = await checkAccess(eventName); - setEmailBalance(data.balances[0].balance); - setHasAccessLoading(false); - setHasAccessResponse(data); - - if (!data.allowed) { - toast.error("You're out of " + eventName); - return; - } - - setSendEventLoading(true); - const eventData = await sendUsage("email"); - setSendEventResponse(eventData); - setSendEventLoading(false); - - setEmailBalance(emailBalance - 1); + // setHasAccessLoading(true); + // const data = await checkAccess(eventName); + // setEmailBalance(data.balances[0].balance); + // setHasAccessLoading(false); + // setHasAccessResponse(data); + // if (!data.allowed) { + // toast.error("You're out of " + eventName); + // return; + // } + // setSendEventLoading(true); + // const eventData = await sendUsage("email"); + // setSendEventResponse(eventData); + // setSendEventLoading(false); + // setEmailBalance(emailBalance - 1); }; return ( @@ -143,35 +121,46 @@ export default function DemoView() { ) : ( <> + + + + - -
-
-

- Upgrade to Pro Plan -

-
- -
-
+ {customer && ( + + + {customer.entitlements.map((entitlement) => ( +
+
+

+ {keyToTitle(entitlement.feature_id)} +

+ + {entitlement.balance || "Allowed"} + +
+ +
+ ))} +
+
+ )}
- + + {/*
@@ -189,9 +178,9 @@ export default function DemoView() { Send Email
- {/* */} + - + */} {hasProFeatures ? (
@@ -317,3 +306,33 @@ const APIPlayground = ({
); }; + +{ + /* + +
+
+

+ Upgrade to Pro Plan +

+
+ +
+
+
*/ +} diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 894a418d8..969dd425c 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,12 +1,12 @@ { "name": "@useautumn/react", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@useautumn/react", - "version": "0.0.6", + "version": "0.0.7", "dependencies": { "@tailwindcss/postcss": "^4.0.3", "class-variance-authority": "^0.7.1", diff --git a/packages/react/package.json b/packages/react/package.json index fff897086..d5539581f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@useautumn/react", - "version": "0.0.6", + "version": "0.0.7", "private": false, "publishConfig": { "access": "public" diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index 026aa98e7..cb4f6c662 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -1,21 +1,22 @@ import { defineConfig } from "tsup"; export default defineConfig([ + { + entry: { + index: "src/index.ts", + }, + dts: true, + clean: false, + banner: { + js: "'use client'", + }, + }, { entry: { "server/index": "src/server/index.ts", // Changed from "server" to "server/index" }, dts: true, clean: true, - }, - { - entry: { - index: "src/index.ts", - }, - dts: true, - clean: true, - banner: { - js: "'use client'", - }, + outDir: "dist", }, ]);