feat: enhance observability and environment variables in wrangler.jsonc; refactor footer component for improved structure; clean up unused types in use-billing hook; update chat handler to utilize environment variables

This commit is contained in:
Aj Wazzan
2025-05-20 01:47:11 -07:00
parent fa6baa7168
commit 97273db862
5 changed files with 30 additions and 46 deletions

View File

@@ -27,16 +27,22 @@ export default function Footer() {
const isInView = useInView(ref, { once: true, margin: '-100px' });
return (
<div className="flex flex-col items-center justify-center bg-[#1A1A1A] rounded-xl m-4" >
<div className="m-4 flex flex-col items-center justify-center rounded-xl bg-[#1A1A1A]">
<div className="">
{/* <div className="h-[527px] w-screen bg-gradient-to-b from-violet-600 via-orange-400 to-slate-950 blur-2xl" /> */}
<div>
<Image src="/gradient.svg" alt="logo" width={1000} height={100} className='w-screen rounded-t-2xl'/>
</div>
<div className="inline-flex justify-center w-full relative bottom-20 lg:bottom-60">
<div>
<img
src="/gradient.svg"
alt="logo"
width={1000}
height={100}
className="w-screen rounded-t-2xl"
/>
</div>
<div className="relative bottom-20 inline-flex w-full justify-center lg:bottom-60">
<div
ref={ref}
className="relative inline-flex flex-col items-center justify-center gap-20 rounded-full w-full"
className="relative inline-flex w-full flex-col items-center justify-center gap-20 rounded-full"
>
<div className="flex flex-col items-center justify-center px-2">
<div className="flex flex-col items-center py-5">
@@ -44,10 +50,9 @@ export default function Footer() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="inline-block text-white lg:bg-gradient-to-b lg:from-[#84878D] lg:via-[#84878D] lg:to-[#1A1A1A] lg:bg-clip-text text-center text-2xl sm:text-4xl md:text-5xl font-bold lg:text-transparent lg:text-8xl"
className="inline-block text-center text-2xl font-bold text-white sm:text-4xl md:text-5xl lg:bg-gradient-to-b lg:from-[#84878D] lg:via-[#84878D] lg:to-[#1A1A1A] lg:bg-clip-text lg:text-8xl lg:text-transparent"
>
<span>Experience the Future of </span> <br />
Email Today
</motion.div>
</div>
@@ -55,10 +60,11 @@ export default function Footer() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="hidden md:flex flex-col items-center justify-start"
className="hidden flex-col items-center justify-start md:flex"
>
<div className="text-lg lg:text-2xl justify-start text-center font-normal leading-7 text-white">
Get started and see how 0.email helps you process your inbox in a fraction of the time.
<div className="justify-start text-center text-lg font-normal leading-7 text-white lg:text-2xl">
Get started and see how 0.email helps you process your inbox in a fraction of the
time.
</div>
</motion.div>
<motion.div

View File

@@ -17,37 +17,6 @@ type Features = {
brainActivity: FeatureState;
};
type Product = {
id: string;
name: string;
[key: string]: any;
};
type Customer = {
id: string;
stripe_id?: string;
products?: Product[];
features?: Feature[];
[key: string]: any;
};
type TrackParams = {
featureId: string;
value: number;
};
type BillingHook = {
customer: Customer | null;
refetch: () => Promise<void>;
attach: (params: { productId: string; successUrl: string; authUrl?: string }) => Promise<void>;
track: (params: TrackParams) => Promise<void>;
openBillingPortal: () => Promise<void>;
isPro: boolean;
chatMessages: FeatureState;
connections: FeatureState;
brainActivity: FeatureState;
};
const DEFAULT_FEATURES: Features = {
chatMessages: {
total: 0,
@@ -86,13 +55,14 @@ const FEATURE_IDS = {
const PRO_PLANS = ['pro-example', 'pro_annual', 'team', 'enterprise'] as const;
export const useBilling = (): BillingHook => {
export const useBilling = () => {
const { customer, refetch } = useCustomer();
console.log('customer', customer);
const { attach, track, openBillingPortal } = useAutumn();
const isPro = useMemo(() => {
if (!customer?.products || !Array.isArray(customer.products)) return false;
return customer.products.some((product: Product) =>
return customer.products.some((product) =>
PRO_PLANS.some((plan) => product.id?.includes(plan) || product.name?.includes(plan)),
);
}, [customer]);

View File

@@ -48,5 +48,5 @@ export const siteConfig = {
'Email Service',
'Web Application',
],
metadataBase: new URL(import.meta.env.VITE_PUBLIC_APP_URL!),
// metadataBase: new URL(import.meta.env.VITE_PUBLIC_APP_URL!),
};

View File

@@ -4,4 +4,11 @@
"compatibility_date": "2025-05-01",
"compatibility_flags": ["nodejs_compat"],
"main": "./worker.ts",
"observability": {
"enabled": true,
},
"vars": {
"VITE_PUBLIC_BACKEND_URL": "https://sapi.0.email",
"VITE_PUBLIC_APP_URL": "https://app.0.email",
},
}

View File

@@ -3,6 +3,7 @@ import { getActiveConnection } from '../lib/server-utils';
import { streamText, generateObject, tool } from 'ai';
import { getContext } from 'hono/context-storage';
import type { HonoContext } from '../ctx';
import { env } from 'cloudflare:workers';
import { openai } from '@ai-sdk/openai';
import { tools } from './agent/tools';
import { Autumn } from 'autumn-js';
@@ -33,7 +34,7 @@ export const chatHandler = async () => {
if (!session) return c.json({ error: 'Unauthorized' }, 401);
console.log('Checking chat permissions for user:', session.user.id);
const canSendMessages = await Autumn.check({
const canSendMessages = await new Autumn({ secretKey: env.AUTUMN_SECRET_KEY }).check({
feature_id: 'chat-messages',
customer_id: session.user.id,
});