data.ai / account-billing-status.tsx
lattmamb's picture
Upload 251 files (#1)
67c7241 verified
import { createClient } from "@/lib/supabase/server";
import { SubmitButton } from "../ui/submit-button";
import { manageSubscription } from "@/lib/actions/billing";
import { PlanComparison, SUBSCRIPTION_PLANS } from "../billing/plan-comparison";
import { isLocalMode } from "@/lib/config";
type Props = {
accountId: string;
returnUrl: string;
}
export default async function AccountBillingStatus({ accountId, returnUrl }: Props) {
// In local development mode, show a simplified component
if (isLocalMode()) {
return (
<div className="rounded-xl border shadow-sm bg-card p-6">
<h2 className="text-xl font-semibold mb-4">Billing Status</h2>
<div className="p-4 mb-4 bg-muted/30 border border-border rounded-lg text-center">
<p className="text-sm text-muted-foreground">
Running in local development mode - billing features are disabled
</p>
<p className="text-xs text-muted-foreground mt-2">
Agent usage limits are not enforced in this environment
</p>
</div>
</div>
);
}
const supabaseClient = await createClient();
// Get account subscription and usage data
const { data: subscriptionData } = await supabaseClient
.schema('basejump')
.from('billing_subscriptions')
.select('*')
.eq('account_id', accountId)
.eq('status', 'active')
.limit(1)
.order('created_at', { ascending: false })
.single();
// Get agent runs for this account
// Get the account's threads
const { data: threads } = await supabaseClient
.from('threads')
.select('thread_id')
.eq('account_id', accountId);
const threadIds = threads?.map(t => t.thread_id) || [];
// Get current month usage
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const isoStartOfMonth = startOfMonth.toISOString();
let totalAgentTime = 0;
let usageDisplay = "No usage this month";
if (threadIds.length > 0) {
const { data: agentRuns } = await supabaseClient
.from('agent_runs')
.select('started_at, completed_at')
.in('thread_id', threadIds)
.gte('started_at', isoStartOfMonth);
if (agentRuns && agentRuns.length > 0) {
const nowTimestamp = now.getTime();
totalAgentTime = agentRuns.reduce((total, run) => {
const startTime = new Date(run.started_at).getTime();
const endTime = run.completed_at
? new Date(run.completed_at).getTime()
: nowTimestamp;
return total + (endTime - startTime) / 1000; // In seconds
}, 0);
// Convert to minutes
const totalMinutes = Math.round(totalAgentTime / 60);
usageDisplay = `${totalMinutes} minutes`;
}
}
const isPlan = (planId?: string) => {
return subscriptionData?.price_id === planId;
};
const planName = isPlan(SUBSCRIPTION_PLANS.FREE)
? "Free"
: isPlan(SUBSCRIPTION_PLANS.PRO)
? "Pro"
: isPlan(SUBSCRIPTION_PLANS.ENTERPRISE)
? "Enterprise"
: "Unknown";
return (
<div className="rounded-xl border shadow-sm bg-card p-6">
<h2 className="text-xl font-semibold mb-4">Billing Status</h2>
{subscriptionData ? (
<>
<div className="mb-6">
<div className="rounded-lg border bg-background p-4 grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-foreground/90">Current Plan</span>
<span className="text-sm font-medium text-card-title">{planName}</span>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-foreground/90">Agent Usage This Month</span>
<span className="text-sm font-medium text-card-title">{usageDisplay}</span>
</div>
</div>
</div>
{/* Plans Comparison */}
<PlanComparison
accountId={accountId}
returnUrl={returnUrl}
className="mb-6"
/>
{/* Manage Subscription Button */}
<form>
<input type="hidden" name="accountId" value={accountId} />
<input type="hidden" name="returnUrl" value={returnUrl} />
<SubmitButton
pendingText="Loading..."
formAction={manageSubscription}
className="w-full bg-primary text-white hover:bg-primary/90 shadow-md hover:shadow-lg transition-all"
>
Manage Subscription
</SubmitButton>
</form>
</>
) : (
<>
<div className="mb-6">
<div className="rounded-lg border bg-background p-4 gap-4">
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-foreground/90">Current Plan</span>
<span className="text-sm font-medium text-card-title">Free</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm font-medium text-foreground/90">Agent Usage This Month</span>
<span className="text-sm font-medium text-card-title">{usageDisplay}</span>
</div>
</div>
</div>
{/* Plans Comparison */}
<PlanComparison
accountId={accountId}
returnUrl={returnUrl}
className="mb-6"
/>
{/* Manage Subscription Button */}
<form>
<input type="hidden" name="accountId" value={accountId} />
<input type="hidden" name="returnUrl" value={returnUrl} />
<SubmitButton
pendingText="Loading..."
formAction={manageSubscription}
className="w-full bg-primary text-white hover:bg-primary/90 shadow-md hover:shadow-lg transition-all"
>
Manage Subscription
</SubmitButton>
</form>
</>
)}
</div>
)
}