From 086a3d85bac0b0e2da2a8f776de067886bea8329 Mon Sep 17 00:00:00 2001 From: Aj Wazzan Date: Mon, 19 May 2025 00:00:36 -0700 Subject: [PATCH] refactor: update AI sidebar and billing hook for improved feature handling and UI adjustments --- .github/CONTRIBUTING.md | 22 ++--- apps/mail/components/ui/ai-sidebar.tsx | 4 +- apps/mail/hooks/use-billing.ts | 112 ++++++++++++++++--------- apps/server/src/lib/auth.ts | 2 +- apps/server/src/main.ts | 2 +- 5 files changed, 81 insertions(+), 61 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 34719d794..fe48225af 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -29,15 +29,9 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo - Clone your fork locally: `git clone https://github.com/YOUR-USERNAME/Zero.git` 2. **Set Up Development Environment** -<<<<<<< HEAD - - Install [Bun](https://bun.sh) - - Clone the repository and install dependencies: `bun install` - - Start the database locally: `bun docker:db:up` -======= - Install [pnpm](https://pnpm.io) - Clone the repository and install dependencies: `pnpm install` - Start the database locally: `pnpm docker:up` ->>>>>>> 7fb24724 (feat: remixify and whatever else needed to be done) - Copy `.env.example` to `.env` in project root - Setup cloudflare with `pnpm run cf-install`, you will need to run this everytime there is a `.env` change - Set up your Google OAuth credentials (see [README.md](../README.md)) @@ -49,11 +43,7 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo ```bash # Start database locally -<<<<<<< HEAD - bun docker:db:up -======= pnpm docker:up ->>>>>>> 7fb24724 (feat: remixify and whatever else needed to be done) # Start the development server pnpm dev @@ -100,8 +90,9 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo git fetch upstream git merge upstream/staging ``` ->[!IMPORTANT] ->Remember to make `staging` branch as your base branch. + + > [!IMPORTANT] + > Remember to make `staging` branch as your base branch. 7. **Push to Your Fork** @@ -114,10 +105,9 @@ Thank you for your interest in contributing to 0.email! We're excited to have yo - Fill out the PR template completely - Link any relevant issues - Add screenshots for UI changes - ->[!IMPORTANT] ->Remember to make your pull request into the `staging` branch - + +> [!IMPORTANT] +> Remember to make your pull request into the `staging` branch ## Database Management diff --git a/apps/mail/components/ui/ai-sidebar.tsx b/apps/mail/components/ui/ai-sidebar.tsx index d4778a6a9..4ea8302e7 100644 --- a/apps/mail/components/ui/ai-sidebar.tsx +++ b/apps/mail/components/ui/ai-sidebar.tsx @@ -486,7 +486,7 @@ function AISidebar({ className }: AISidebarProps) { isFullScreen={isFullScreen} isPopup={isPopup} chatMessages={chatMessages} - isPro={isPro} + isPro={isPro ?? false} onUpgrade={handleUpgrade} onNewChat={handleNewChat} /> @@ -532,7 +532,7 @@ function AISidebar({ className }: AISidebarProps) { isFullScreen={isFullScreen} isPopup={isPopup} chatMessages={chatMessages} - isPro={isPro} + isPro={isPro ?? false} onUpgrade={handleUpgrade} onNewChat={handleNewChat} /> diff --git a/apps/mail/hooks/use-billing.ts b/apps/mail/hooks/use-billing.ts index e730e2e9f..d79508a1a 100644 --- a/apps/mail/hooks/use-billing.ts +++ b/apps/mail/hooks/use-billing.ts @@ -1,18 +1,14 @@ import { useAutumn, useCustomer } from 'autumn-js/react'; import { useMemo } from 'react'; -type Feature = { - feature_id: string; - included_usage: number; - balance: number; - unlimited: boolean; -}; - type FeatureState = { total: number; remaining: number; unlimited: boolean; enabled: boolean; + usage: number; + nextResetAt: number | null; + interval: string; }; type Features = { @@ -53,9 +49,33 @@ type BillingHook = { }; const DEFAULT_FEATURES: Features = { - chatMessages: { total: 0, remaining: 0, unlimited: false, enabled: false }, - connections: { total: 0, remaining: 0, unlimited: false, enabled: false }, - brainActivity: { total: 0, remaining: 0, unlimited: false, enabled: false }, + chatMessages: { + total: 0, + remaining: 0, + unlimited: false, + enabled: false, + usage: 0, + nextResetAt: null, + interval: '', + }, + connections: { + total: 0, + remaining: 0, + unlimited: false, + enabled: false, + usage: 0, + nextResetAt: null, + interval: '', + }, + brainActivity: { + total: 0, + remaining: 0, + unlimited: false, + enabled: false, + usage: 0, + nextResetAt: null, + interval: '', + }, }; const FEATURE_IDS = { @@ -78,38 +98,48 @@ export const useBilling = (): BillingHook => { }, [customer]); const customerFeatures = useMemo(() => { - if (!customer || !customer.features || !Array.isArray(customer.features)) - return DEFAULT_FEATURES; + if (!customer?.features) return DEFAULT_FEATURES; - const features = customer.features.reduce( - (acc: Features, feature: Feature) => { - const id = feature.feature_id; - if (id === FEATURE_IDS.CHAT) { - acc.chatMessages = { - total: feature.included_usage || 0, - remaining: feature.balance || 0, - unlimited: feature.unlimited, - enabled: feature.unlimited || Number(feature.balance) > 0, - }; - } else if (id === FEATURE_IDS.CONNECTIONS) { - acc.connections = { - total: feature.included_usage || 0, - remaining: feature.balance || 0, - unlimited: feature.unlimited, - enabled: feature.unlimited || Number(feature.balance) > 0, - }; - } else if (id === FEATURE_IDS.BRAIN) { - acc.brainActivity = { - total: feature.included_usage || 0, - remaining: feature.balance || 0, - unlimited: feature.unlimited, - enabled: feature.unlimited || Number(feature.balance) > 0, - }; - } - return acc; - }, - { ...DEFAULT_FEATURES }, - ); + const features = { ...DEFAULT_FEATURES }; + + if (customer.features[FEATURE_IDS.CHAT]) { + const feature = customer.features[FEATURE_IDS.CHAT]; + features.chatMessages = { + total: feature.included_usage || 0, + remaining: feature.balance || 0, + unlimited: feature.unlimited ?? false, + enabled: (feature.unlimited ?? false) || Number(feature.balance) > 0, + usage: feature.usage || 0, + nextResetAt: feature.next_reset_at ?? null, + interval: feature.interval || '', + }; + } + + if (customer.features[FEATURE_IDS.CONNECTIONS]) { + const feature = customer.features[FEATURE_IDS.CONNECTIONS]; + features.connections = { + total: feature.included_usage || 0, + remaining: feature.balance || 0, + unlimited: feature.unlimited ?? false, + enabled: (feature.unlimited ?? false) || Number(feature.balance) > 0, + usage: feature.usage || 0, + nextResetAt: feature.next_reset_at ?? null, + interval: feature.interval || '', + }; + } + + if (customer.features[FEATURE_IDS.BRAIN]) { + const feature = customer.features[FEATURE_IDS.BRAIN]; + features.brainActivity = { + total: feature.included_usage || 0, + remaining: feature.balance || 0, + unlimited: feature.unlimited ?? false, + enabled: (feature.unlimited ?? false) || Number(feature.balance) > 0, + usage: feature.usage || 0, + nextResetAt: feature.next_reset_at ?? null, + interval: feature.interval || '', + }; + } return features; }, [customer]); diff --git a/apps/server/src/lib/auth.ts b/apps/server/src/lib/auth.ts index 3770d8698..248ff0480 100644 --- a/apps/server/src/lib/auth.ts +++ b/apps/server/src/lib/auth.ts @@ -222,7 +222,7 @@ const createAuthConfig = () => { }, }, baseURL: env.VITE_PUBLIC_BACKEND_URL, - trustedOrigins: [env.VITE_PUBLIC_APP_URL, env.VITE_PUBLIC_BACKEND_URL], + trustedOrigins: ['https://app.0.email', 'https://sapi.0.email'], session: { cookieCache: { enabled: true, diff --git a/apps/server/src/main.ts b/apps/server/src/main.ts index 5c456b048..2e0a4d858 100644 --- a/apps/server/src/main.ts +++ b/apps/server/src/main.ts @@ -68,7 +68,7 @@ const app = new Hono() .use( '*', cors({ - origin: () => env.VITE_PUBLIC_APP_URL, + origin: (c) => c, credentials: true, allowHeaders: ['Content-Type', 'Authorization'], exposeHeaders: ['X-Zero-Redirect'],